1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.buffer;
17
18 import io.netty.microbench.util.AbstractMicrobenchmark;
19 import org.openjdk.jmh.annotations.Benchmark;
20 import org.openjdk.jmh.annotations.BenchmarkMode;
21 import org.openjdk.jmh.annotations.Measurement;
22 import org.openjdk.jmh.annotations.Mode;
23 import org.openjdk.jmh.annotations.OutputTimeUnit;
24 import org.openjdk.jmh.annotations.Param;
25 import org.openjdk.jmh.annotations.Scope;
26 import org.openjdk.jmh.annotations.Setup;
27 import org.openjdk.jmh.annotations.State;
28 import org.openjdk.jmh.annotations.TearDown;
29 import org.openjdk.jmh.annotations.Warmup;
30
31 import java.util.concurrent.TimeUnit;
32
33 @State(Scope.Benchmark)
34 @BenchmarkMode(Mode.AverageTime)
35 @OutputTimeUnit(TimeUnit.NANOSECONDS)
36 @Warmup(iterations = 10, time = 400, timeUnit = TimeUnit.MILLISECONDS)
37 @Measurement(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
38 public class ByteBufZeroingBenchmark extends AbstractMicrobenchmark {
39
40 @Param({
41 "1",
42 "2",
43 "3",
44 "4",
45 "7",
46 "8",
47 "15",
48 "64",
49 "65",
50 "1024",
51 })
52 private int bytes = 1024;
53 @Param({
54 "true",
55 "false",
56 })
57 private boolean direct;
58 @Param({
59 "true",
60 "false",
61 })
62 private boolean pooled;
63 @Param({
64 "false",
65 })
66 public String checkAccessible;
67
68 @Param({
69 "false",
70 })
71 public String checkBounds;
72 @Param({
73 "0",
74 "1",
75 })
76 public int startOffset;
77 private ByteBuf buffer;
78 private int offset;
79
80 @Setup
81 public void setup() {
82 System.setProperty("io.netty.buffer.checkAccessible", checkAccessible);
83 System.setProperty("io.netty.buffer.checkBounds", checkBounds);
84 ByteBufAllocator allocator = pooled? PooledByteBufAllocator.DEFAULT : UnpooledByteBufAllocator.DEFAULT;
85 int capacityRequired = startOffset + bytes;
86 offset = 0;
87 buffer = direct? alignedDirectAllocation(allocator, capacityRequired, 8) :
88 allocator.heapBuffer(capacityRequired, capacityRequired);
89 if (startOffset > 0) {
90 offset += startOffset;
91 }
92 }
93
94 private ByteBuf alignedDirectAllocation(ByteBufAllocator allocator, int bytes, final int alignment) {
95 ByteBuf buffer = allocator.directBuffer(bytes + alignment, bytes + alignment);
96 final long address = buffer.memoryAddress();
97 final int remainder = (int) address % alignment;
98 final int nextAlignedOffset = alignment - remainder;
99 this.offset = nextAlignedOffset;
100 return buffer;
101 }
102
103 @Benchmark
104 public ByteBuf setZero() {
105 final ByteBuf buffer = this.buffer;
106 buffer.setZero(offset, bytes);
107 return buffer;
108 }
109
110 @Benchmark
111 public ByteBuf setBytes() {
112 final ByteBuf buffer = this.buffer;
113 final int offset = this.offset;
114 for (int i = 0; i < bytes; i++) {
115 buffer.setByte(offset + i, 0);
116 }
117 return buffer;
118 }
119
120 @TearDown
121 public void teardown() {
122 buffer.release();
123 }
124
125 }