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 io.netty.util.internal.ConstantTimeUtils;
23 import io.netty.util.internal.PlatformDependent;
24 import org.openjdk.jmh.annotations.Benchmark;
25 import org.openjdk.jmh.annotations.Level;
26 import org.openjdk.jmh.annotations.Measurement;
27 import org.openjdk.jmh.annotations.Param;
28 import org.openjdk.jmh.annotations.Setup;
29 import org.openjdk.jmh.annotations.Threads;
30 import org.openjdk.jmh.annotations.Warmup;
31
32 import java.util.List;
33
34 import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE;
35 import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE;
36
37 @Threads(1)
38 @Warmup(iterations = 5)
39 @Measurement(iterations = 5)
40 public class HpackUtilBenchmark extends AbstractMicrobenchmark {
41 @Param
42 public HpackHeadersSize size;
43
44 private List<HpackHeader> hpackHeaders;
45
46 @Setup(Level.Trial)
47 public void setup() {
48 hpackHeaders = HpackBenchmarkUtil.headers(size, false);
49 }
50
51 @Benchmark
52 public int oldEquals() {
53 int count = 0;
54 for (int i = 0; i < hpackHeaders.size(); ++i) {
55 HpackHeader hpackHeader = hpackHeaders.get(i);
56 if (oldEquals(hpackHeader.name, hpackHeader.name)) {
57 ++count;
58 }
59 }
60 return count;
61 }
62
63 @Benchmark
64 public int newEquals() {
65 int count = 0;
66 for (int i = 0; i < hpackHeaders.size(); ++i) {
67 HpackHeader hpackHeader = hpackHeaders.get(i);
68 if (newEquals(hpackHeader.name, hpackHeader.name)) {
69 ++count;
70 }
71 }
72 return count;
73 }
74
75 private static boolean oldEquals(CharSequence s1, CharSequence s2) {
76 if (s1.length() != s2.length()) {
77 return false;
78 }
79 char c = 0;
80 for (int i = 0; i < s1.length(); i++) {
81 c |= s1.charAt(i) ^ s2.charAt(i);
82 }
83 return c == 0;
84 }
85
86 private static boolean newEquals(CharSequence s1, CharSequence s2) {
87 if (s1 instanceof AsciiString && s2 instanceof AsciiString) {
88 if (s1.length() != s2.length()) {
89 return false;
90 }
91 AsciiString s1Ascii = (AsciiString) s1;
92 AsciiString s2Ascii = (AsciiString) s2;
93 return PlatformDependent.equalsConstantTime(s1Ascii.array(), s1Ascii.arrayOffset(),
94 s2Ascii.array(), s2Ascii.arrayOffset(), s1.length()) != 0;
95 }
96
97 return ConstantTimeUtils.equalsConstantTime(s1, s2) != 0;
98 }
99
100 static HpackEncoder newTestEncoder() {
101 HpackEncoder hpackEncoder = new HpackEncoder();
102 ByteBuf buf = Unpooled.buffer();
103 try {
104 hpackEncoder.setMaxHeaderTableSize(buf, MAX_HEADER_TABLE_SIZE);
105 hpackEncoder.setMaxHeaderListSize(MAX_HEADER_LIST_SIZE);
106 } catch (Http2Exception e) {
107 throw new Error("max size not allowed?", e);
108 } finally {
109 buf.release();
110 }
111 return hpackEncoder;
112 }
113 }