blob: 4a7515a7a1d467b1b7f5a0d7636652c42f387264 [file] [log] [blame]
/*
* Copyright 2016 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.netty;
import static io.grpc.netty.Utils.CONTENT_TYPE_HEADER;
import static io.grpc.netty.Utils.TE_TRAILERS;
import static io.netty.util.AsciiString.of;
import io.grpc.netty.GrpcHttp2HeadersUtils.GrpcHttp2RequestHeaders;
import io.grpc.netty.GrpcHttp2HeadersUtils.GrpcHttp2ResponseHeaders;
import io.netty.handler.codec.http2.DefaultHttp2Headers;
import io.netty.handler.codec.http2.Http2Headers;
import io.netty.util.AsciiString;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.CompilerControl;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
/**
* Benchmarks for {@link GrpcHttp2RequestHeaders} and {@link GrpcHttp2ResponseHeaders}.
*/
@State(Scope.Thread)
public class InboundHeadersBenchmark {
private static AsciiString[] requestHeaders;
private static AsciiString[] responseHeaders;
static {
setupRequestHeaders();
setupResponseHeaders();
}
// Headers taken from the gRPC spec.
private static void setupRequestHeaders() {
requestHeaders = new AsciiString[18];
int i = 0;
requestHeaders[i++] = of(":method");
requestHeaders[i++] = of("POST");
requestHeaders[i++] = of(":scheme");
requestHeaders[i++] = of("http");
requestHeaders[i++] = of(":path");
requestHeaders[i++] = of("/google.pubsub.v2.PublisherService/CreateTopic");
requestHeaders[i++] = of(":authority");
requestHeaders[i++] = of("pubsub.googleapis.com");
requestHeaders[i++] = of("te");
requestHeaders[i++] = of("trailers");
requestHeaders[i++] = of("grpc-timeout");
requestHeaders[i++] = of("1S");
requestHeaders[i++] = of("content-type");
requestHeaders[i++] = of("application/grpc+proto");
requestHeaders[i++] = of("grpc-encoding");
requestHeaders[i++] = of("gzip");
requestHeaders[i++] = of("authorization");
requestHeaders[i] = of("Bearer y235.wef315yfh138vh31hv93hv8h3v");
}
private static void setupResponseHeaders() {
responseHeaders = new AsciiString[4];
int i = 0;
responseHeaders[i++] = of(":status");
responseHeaders[i++] = of("200");
responseHeaders[i++] = of("grpc-encoding");
responseHeaders[i] = of("gzip");
}
/**
* Checkstyle.
*/
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void grpcHeaders_serverHandler(Blackhole bh) {
serverHandler(bh, new GrpcHttp2RequestHeaders(4));
}
/**
* Checkstyle.
*/
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void defaultHeaders_serverHandler(Blackhole bh) {
serverHandler(bh, new DefaultHttp2Headers(true, 9));
}
/**
* Checkstyle.
*/
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void grpcHeaders_clientHandler(Blackhole bh) {
clientHandler(bh, new GrpcHttp2ResponseHeaders(2));
}
/**
* Checkstyle.
*/
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void defaultHeaders_clientHandler(Blackhole bh) {
clientHandler(bh, new DefaultHttp2Headers(true, 2));
}
@CompilerControl(CompilerControl.Mode.INLINE)
private static void serverHandler(Blackhole bh, Http2Headers headers) {
for (int i = 0; i < requestHeaders.length; i += 2) {
bh.consume(headers.add(requestHeaders[i], requestHeaders[i + 1]));
}
// Sequence of headers accessed in NettyServerHandler
bh.consume(headers.get(TE_TRAILERS));
bh.consume(headers.get(CONTENT_TYPE_HEADER));
bh.consume(headers.method());
bh.consume(headers.get(CONTENT_TYPE_HEADER));
bh.consume(headers.path());
bh.consume(Utils.convertHeaders(headers));
}
@CompilerControl(CompilerControl.Mode.INLINE)
private static void clientHandler(Blackhole bh, Http2Headers headers) {
// NettyClientHandler does not directly access headers, but convert to Metadata immediately.
bh.consume(headers.add(responseHeaders[0], responseHeaders[1]));
bh.consume(headers.add(responseHeaders[2], responseHeaders[3]));
bh.consume(Utils.convertHeaders(headers));
}
// /**
// * Prints the size of the header objects in bytes. Needs JOL (Java Object Layout) as a
// * dependency.
// */
// public static void main(String... args) {
// Http2Headers grpcRequestHeaders = new GrpcHttp2RequestHeaders(4);
// Http2Headers defaultRequestHeaders = new DefaultHttp2Headers(true, 9);
// for (int i = 0; i < requestHeaders.length; i += 2) {
// grpcRequestHeaders.add(requestHeaders[i], requestHeaders[i + 1]);
// defaultRequestHeaders.add(requestHeaders[i], requestHeaders[i + 1]);
// }
// long c = 10L;
// int m = ((int) c) / 20;
//
// long grpcRequestHeadersBytes = GraphLayout.parseInstance(grpcRequestHeaders).totalSize();
// long defaultRequestHeadersBytes =
// GraphLayout.parseInstance(defaultRequestHeaders).totalSize();
//
// System.out.printf("gRPC Request Headers: %d bytes%nNetty Request Headers: %d bytes%n",
// grpcRequestHeadersBytes, defaultRequestHeadersBytes);
//
// Http2Headers grpcResponseHeaders = new GrpcHttp2RequestHeaders(4);
// Http2Headers defaultResponseHeaders = new DefaultHttp2Headers(true, 9);
// for (int i = 0; i < responseHeaders.length; i += 2) {
// grpcResponseHeaders.add(responseHeaders[i], responseHeaders[i + 1]);
// defaultResponseHeaders.add(responseHeaders[i], responseHeaders[i + 1]);
// }
//
// long grpcResponseHeadersBytes = GraphLayout.parseInstance(grpcResponseHeaders).totalSize();
// long defaultResponseHeadersBytes =
// GraphLayout.parseInstance(defaultResponseHeaders).totalSize();
//
// System.out.printf("gRPC Response Headers: %d bytes%nNetty Response Headers: %d bytes%n",
// grpcResponseHeadersBytes, defaultResponseHeadersBytes);
// }
}