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 io.netty.util.ByteProcessor;
20
21 import org.openjdk.jmh.annotations.Benchmark;
22 import org.openjdk.jmh.annotations.Measurement;
23 import org.openjdk.jmh.annotations.Param;
24 import org.openjdk.jmh.annotations.Setup;
25 import org.openjdk.jmh.annotations.TearDown;
26 import org.openjdk.jmh.annotations.Warmup;
27
28 import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
29 import static io.netty.buffer.Unpooled.wrappedBuffer;
30
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.concurrent.TimeUnit;
34
35 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
36 @Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
37 public class CompositeByteBufSequentialBenchmark extends AbstractMicrobenchmark {
38
39 public enum ByteBufType {
40 SMALL_CHUNKS {
41 @Override
42 ByteBuf newBuffer(int length) {
43 return newBufferSmallChunks(length);
44 }
45 },
46 LARGE_CHUNKS {
47 @Override
48 ByteBuf newBuffer(int length) {
49 return newBufferLargeChunks(length);
50 }
51 };
52 abstract ByteBuf newBuffer(int length);
53 }
54
55 @Param({
56 "8",
57 "64",
58 "1024",
59 "10240",
60 "102400",
61 "1024000",
62 })
63 public int size;
64
65 @Param
66 public ByteBufType bufferType;
67
68 private ByteBuf buffer;
69
70 @Setup
71 public void setup() {
72 buffer = bufferType.newBuffer(size);
73 }
74
75 @TearDown
76 public void teardown() {
77 buffer.release();
78 }
79
80 private static final ByteProcessor TEST_PROCESSOR = new ByteProcessor() {
81 @Override
82 public boolean process(byte value) throws Exception {
83 return value == 'b';
84 }
85 };
86
87 @Benchmark
88 public int forEachByte() {
89 buffer.setIndex(0, buffer.capacity());
90 buffer.forEachByte(TEST_PROCESSOR);
91 return buffer.forEachByteDesc(TEST_PROCESSOR);
92 }
93
94 @Benchmark
95 public int sequentialWriteAndRead() {
96 buffer.clear();
97 for (int i = 0, l = buffer.writableBytes(); i < l; i++) {
98 buffer.writeByte('a');
99 }
100 for (int i = 0, l = buffer.readableBytes(); i < l; i++) {
101 if (buffer.readByte() == 'b') {
102 return -1;
103 }
104 }
105 return 1;
106 }
107
108 private static ByteBuf newBufferSmallChunks(int length) {
109
110 List<ByteBuf> buffers = new ArrayList<ByteBuf>(((length + 1) / 45) * 19);
111 for (int i = 0; i < length + 45; i += 45) {
112 for (int j = 1; j <= 9; j++) {
113 buffers.add(EMPTY_BUFFER);
114 buffers.add(wrappedBuffer(new byte[j]));
115 }
116 buffers.add(EMPTY_BUFFER);
117 }
118
119 ByteBuf buffer = wrappedBuffer(Integer.MAX_VALUE, buffers.toArray(new ByteBuf[0]));
120
121
122 return buffer.capacity(length).writerIndex(0);
123 }
124
125 private static ByteBuf newBufferLargeChunks(int length) {
126
127 List<ByteBuf> buffers = new ArrayList<ByteBuf>((length + 1) / 512);
128 for (int i = 0; i < length + 1536; i += 1536) {
129 buffers.add(wrappedBuffer(new byte[512]));
130 buffers.add(EMPTY_BUFFER);
131 buffers.add(wrappedBuffer(new byte[1024]));
132 }
133
134 ByteBuf buffer = wrappedBuffer(Integer.MAX_VALUE, buffers.toArray(new ByteBuf[0]));
135
136
137 return buffer.capacity(length).writerIndex(0);
138 }
139 }