1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec.http;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.microbench.util.AbstractMicrobenchmark;
20 import io.netty5.util.AsciiString;
21 import io.netty5.util.CharsetUtil;
22 import org.openjdk.jmh.annotations.Benchmark;
23 import org.openjdk.jmh.annotations.Measurement;
24 import org.openjdk.jmh.annotations.Scope;
25 import org.openjdk.jmh.annotations.State;
26 import org.openjdk.jmh.annotations.Warmup;
27
28 import static io.netty5.buffer.api.DefaultBufferAllocators.preferredAllocator;
29 import static io.netty5.handler.codec.http.HttpConstants.CR;
30 import static io.netty5.handler.codec.http.HttpConstants.LF;
31 import static io.netty5.handler.codec.http.HttpConstants.SP;
32 import static java.nio.charset.StandardCharsets.US_ASCII;
33
34 @State(Scope.Benchmark)
35 @Warmup(iterations = 10)
36 @Measurement(iterations = 20)
37 public class HttpRequestEncoderInsertBenchmark extends AbstractMicrobenchmark {
38
39 private final String uri = "http://localhost?eventType=CRITICAL&from=0&to=1497437160327&limit=10&offset=0";
40 private final OldHttpRequestEncoder encoderOld = new OldHttpRequestEncoder();
41 private final HttpRequestEncoder encoderNew = new HttpRequestEncoder();
42
43 @Benchmark
44 public Buffer oldEncoder() {
45 try (Buffer buffer = preferredAllocator().allocate(100)) {
46 encoderOld.encodeInitialLine(buffer, new DefaultHttpRequest(HttpVersion.HTTP_1_1,
47 HttpMethod.GET, uri));
48 return buffer;
49 }
50 }
51
52 @Benchmark
53 public Buffer newEncoder() throws Exception {
54 try (Buffer buffer = preferredAllocator().allocate(100)) {
55 encoderNew.encodeInitialLine(buffer, new DefaultHttpRequest(HttpVersion.HTTP_1_1,
56 HttpMethod.GET, uri));
57 return buffer;
58 }
59 }
60
61 private static class OldHttpRequestEncoder extends HttpObjectEncoder<HttpRequest> {
62 private static final byte[] CRLF = {CR, LF};
63 private static final char SLASH = '/';
64 private static final char QUESTION_MARK = '?';
65
66 @Override
67 public boolean acceptOutboundMessage(Object msg) throws Exception {
68 return super.acceptOutboundMessage(msg) && !(msg instanceof HttpResponse);
69 }
70
71 @Override
72 protected void encodeInitialLine(Buffer buf, HttpRequest request) {
73 AsciiString method = request.method().asciiName();
74 buf.writeCharSequence(method, US_ASCII);
75 buf.writeByte(SP);
76
77
78
79 String uri = request.uri();
80
81 if (uri.isEmpty()) {
82 uri += SLASH;
83 } else {
84 int start = uri.indexOf("://");
85 if (start != -1 && uri.charAt(0) != SLASH) {
86 int startIndex = start + 3;
87
88
89 int index = uri.indexOf(QUESTION_MARK, startIndex);
90 if (index == -1) {
91 if (uri.lastIndexOf(SLASH) <= startIndex) {
92 uri += SLASH;
93 }
94 } else {
95 if (uri.lastIndexOf(SLASH, index) <= startIndex) {
96 int len = uri.length();
97 StringBuilder sb = new StringBuilder(len + 1);
98 sb.append(uri, 0, index)
99 .append(SLASH)
100 .append(uri, index, len);
101 uri = sb.toString();
102 }
103 }
104 }
105 }
106
107 buf.writeBytes(uri.getBytes(CharsetUtil.UTF_8));
108
109 buf.writeByte(SP);
110 request.protocolVersion().encode(buf);
111 buf.writeBytes(CRLF);
112 }
113 }
114 }