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.handler.codec.http2.Http2Headers.PseudoHeaderName;
19 import io.netty.microbench.util.AbstractMicrobenchmark;
20 import io.netty.util.AsciiString;
21 import org.openjdk.jmh.annotations.Benchmark;
22 import org.openjdk.jmh.annotations.BenchmarkMode;
23 import org.openjdk.jmh.annotations.CompilerControl;
24 import org.openjdk.jmh.annotations.Measurement;
25 import org.openjdk.jmh.annotations.Mode;
26 import org.openjdk.jmh.annotations.OutputTimeUnit;
27 import org.openjdk.jmh.annotations.Param;
28 import org.openjdk.jmh.annotations.Scope;
29 import org.openjdk.jmh.annotations.Setup;
30 import org.openjdk.jmh.annotations.State;
31 import org.openjdk.jmh.annotations.Warmup;
32 import org.openjdk.jmh.infra.Blackhole;
33
34 import java.util.concurrent.TimeUnit;
35
36
37 @State(Scope.Benchmark)
38 @Warmup(iterations = 10, time = 200, timeUnit = TimeUnit.MILLISECONDS)
39 @Measurement(iterations = 10, time = 200, timeUnit = TimeUnit.MILLISECONDS)
40 @BenchmarkMode(Mode.AverageTime)
41 @OutputTimeUnit(TimeUnit.NANOSECONDS)
42 public class Http2PseudoHeadersLookupBenchmark extends AbstractMicrobenchmark {
43
44 @Param({ "true", "false" })
45 public boolean same;
46
47 private AsciiString[] asciiStrings;
48 private String[] strings;
49
50 private DefaultHttp2Headers headers;
51 @Setup
52 public void init() {
53
54
55
56
57 PseudoHeaderName[] pseudoHeaderNames = PseudoHeaderName.values();
58 asciiStrings = new AsciiString[pseudoHeaderNames.length];
59 strings = new String[pseudoHeaderNames.length];
60 for (int i = 0; i < pseudoHeaderNames.length; i++) {
61 PseudoHeaderName pseudoHeaderName = pseudoHeaderNames[i];
62 asciiStrings[i] = same? pseudoHeaderName.value() : new AsciiString(pseudoHeaderName.value().array(), true);
63 byte[] chars = asciiStrings[i].array();
64 strings[i] = same? pseudoHeaderName.value().toString() : new String(chars, 0, 0, chars.length);
65
66 asciiStrings[i].hashCode();
67 pseudoHeaderName.hashCode();
68 pseudoHeaderName.toString().hashCode();
69 strings[i].hashCode();
70 }
71 this.headers = new DefaultHttp2Headers();
72 }
73
74 @Benchmark
75 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
76 public void getAsciiStringPseudoHeader(Blackhole bh) {
77 for (AsciiString asciiString : asciiStrings) {
78 bh.consume(PseudoHeaderName.getPseudoHeader(asciiString));
79 }
80 }
81
82 @Benchmark
83 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
84 public void getStringPseudoHeader(Blackhole bh) {
85 for (String string : strings) {
86 bh.consume(PseudoHeaderName.getPseudoHeader(string));
87 }
88 }
89
90 @Benchmark
91 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
92 public void addAsciiStringInHttp2Headers(Blackhole bh) {
93 DefaultHttp2Headers headers = this.headers;
94 for (AsciiString asciiString : asciiStrings) {
95 boolean hasPrefix = PseudoHeaderName.hasPseudoHeaderFormat(asciiString);
96 if (hasPrefix) {
97 boolean isPseudoHeader = PseudoHeaderName.isPseudoHeader(asciiString);
98 if (isPseudoHeader) {
99 bh.consume(headers.add(asciiString, "0"));
100 headers.clear();
101 }
102 }
103 }
104 }
105
106 @Benchmark
107 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
108 public void addStringInHttp2Headers(Blackhole bh) {
109 DefaultHttp2Headers headers = this.headers;
110 for (String asciiString : strings) {
111 boolean hasPrefix = PseudoHeaderName.hasPseudoHeaderFormat(asciiString);
112 if (hasPrefix) {
113 boolean isPseudoHeader = PseudoHeaderName.isPseudoHeader(asciiString);
114 if (isPseudoHeader) {
115 bh.consume(headers.add(asciiString, "0"));
116 headers.clear();
117 }
118 }
119 }
120 }
121 }