1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http2;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import io.netty.microbench.util.AbstractMicrobenchmark;
21 import io.netty.util.AsciiString;
22 import org.openjdk.jmh.annotations.Benchmark;
23 import org.openjdk.jmh.annotations.BenchmarkMode;
24 import org.openjdk.jmh.annotations.Fork;
25 import org.openjdk.jmh.annotations.Measurement;
26 import org.openjdk.jmh.annotations.Mode;
27 import org.openjdk.jmh.annotations.OutputTimeUnit;
28 import org.openjdk.jmh.annotations.Param;
29 import org.openjdk.jmh.annotations.Scope;
30 import org.openjdk.jmh.annotations.Setup;
31 import org.openjdk.jmh.annotations.State;
32 import org.openjdk.jmh.annotations.Threads;
33 import org.openjdk.jmh.annotations.Warmup;
34 import org.openjdk.jmh.infra.Blackhole;
35
36 import java.util.Random;
37 import java.util.concurrent.TimeUnit;
38
39 @Fork(5)
40 @Threads(1)
41 @State(Scope.Benchmark)
42 @Warmup(iterations = 5)
43 @Measurement(iterations = 5)
44 @OutputTimeUnit(TimeUnit.NANOSECONDS)
45 @BenchmarkMode(Mode.AverageTime)
46 public class HpackEncoderBenchmarkUniqueValues extends AbstractMicrobenchmark {
47
48 @Param({"fewHeaders", "manyPaths", "tracesWithUniqueValues"})
49 private String type;
50
51 private final AsciiString[] PATHS = generateRandomPaths(20);
52
53 private final Random r = new Random();
54
55 private final Http2Headers[] http2Headers = new Http2Headers[1000];
56
57 private final HpackEncoder[] hpackEncoder = new HpackEncoder[1000];
58
59 private final ByteBuf output = Unpooled.buffer(10, 10000);
60
61 @Setup
62 public void setup() throws Http2Exception {
63 for (int i = 0; i < http2Headers.length; i++) {
64 DefaultHttp2Headers headers = new DefaultHttp2Headers();
65 if (type.equals("tracesWithUniqueValues")) {
66 headers.add(AsciiString.of("traceid"), randomAsciiString(20));
67 }
68 headers.add(AsciiString.of("key1"), AsciiString.of("value1"));
69 headers.add(AsciiString.of("key12"), AsciiString.of("value12"));
70 headers.add(AsciiString.of("key123"), AsciiString.of("value123"));
71 if (type.equals("manyPaths")) {
72 headers.add(AsciiString.of(":path"), AsciiString.of("/path/to/" + PATHS[r.nextInt(PATHS.length)]));
73 }
74 headers.add(AsciiString.of(":method"), AsciiString.of("POST"));
75 headers.add(AsciiString.of("content-encoding"), AsciiString.of("grpc-encoding"));
76 http2Headers[i] = headers;
77 }
78
79 for (int i = 0; i < hpackEncoder.length; i++) {
80 hpackEncoder[i] = new HpackEncoder();
81 for (Http2Headers headers: http2Headers) {
82 output.clear();
83 hpackEncoder[i].encodeHeaders(3, output, headers, Http2HeadersEncoder.NEVER_SENSITIVE);
84 }
85 }
86 }
87
88 @Benchmark
89 public void encode(Blackhole bh) throws Exception {
90 output.clear();
91
92 Http2Headers headers = http2Headers[r.nextInt(http2Headers.length)];
93
94
95 HpackEncoder encoder = hpackEncoder[r.nextInt(hpackEncoder.length)];
96 encoder.encodeHeaders(3, output, headers, Http2HeadersEncoder.NEVER_SENSITIVE);
97
98 bh.consume(output);
99 }
100
101 private static AsciiString[] generateRandomPaths(int size) {
102 AsciiString[] paths = new AsciiString[size];
103 for (int i = 0; i < size; i++) {
104 paths[i] = randomAsciiString(20);
105 }
106 return paths;
107 }
108
109 private static AsciiString randomAsciiString(int length) {
110 return AsciiString.of(HpackHeader.createHeaders(1, 10, length, true).get(0).value);
111 }
112
113 }