1 /* 2 * Copyright 2016 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.netty; 18 19 import io.grpc.Metadata; 20 import io.grpc.Metadata.AsciiMarshaller; 21 import io.netty.buffer.ByteBuf; 22 import io.netty.buffer.UnpooledByteBufAllocator; 23 import io.netty.handler.codec.http2.DefaultHttp2HeadersEncoder; 24 import io.netty.handler.codec.http2.Http2Headers; 25 import io.netty.handler.codec.http2.Http2HeadersEncoder; 26 import io.netty.util.AsciiString; 27 import java.util.UUID; 28 import java.util.concurrent.TimeUnit; 29 import org.openjdk.jmh.annotations.Benchmark; 30 import org.openjdk.jmh.annotations.BenchmarkMode; 31 import org.openjdk.jmh.annotations.Mode; 32 import org.openjdk.jmh.annotations.OutputTimeUnit; 33 import org.openjdk.jmh.annotations.Param; 34 import org.openjdk.jmh.annotations.Scope; 35 import org.openjdk.jmh.annotations.Setup; 36 import org.openjdk.jmh.annotations.State; 37 38 /** 39 * Header encoding benchmark. 40 */ 41 @State(Scope.Benchmark) 42 public class OutboundHeadersBenchmark { 43 @Param({"1", "5", "10", "20"}) 44 public int headerCount; 45 46 private final AsciiMarshaller<String> keyMarshaller = new AsciiMarshaller<String>() { 47 @Override 48 public String toAsciiString(String value) { 49 return value; 50 } 51 52 @Override 53 public String parseAsciiString(String serialized) { 54 return serialized; 55 } 56 }; 57 58 private final Metadata metadata = new Metadata(); 59 private final AsciiString scheme = new AsciiString("https"); 60 private final AsciiString defaultPath = new AsciiString("/Service.MethodMethodMethod"); 61 private final AsciiString authority = new AsciiString("authority.googleapis.bogus"); 62 private final AsciiString userAgent = new AsciiString("grpc-java-netty"); 63 private final Http2HeadersEncoder headersEncoder = new DefaultHttp2HeadersEncoder(); 64 private final ByteBuf scratchBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(4096); 65 66 @Setup setUp()67 public void setUp() throws Exception { 68 for (int i = 0; i < headerCount; i++) { 69 metadata.put(Metadata.Key.of("key-" + i, keyMarshaller), UUID.randomUUID().toString()); 70 } 71 } 72 73 @Benchmark 74 @BenchmarkMode(Mode.SampleTime) 75 @OutputTimeUnit(TimeUnit.NANOSECONDS) convertClientHeaders()76 public Http2Headers convertClientHeaders() { 77 return Utils.convertClientHeaders(metadata, scheme, defaultPath, authority, Utils.HTTP_METHOD, 78 userAgent); 79 } 80 81 @Benchmark 82 @BenchmarkMode(Mode.SampleTime) 83 @OutputTimeUnit(TimeUnit.NANOSECONDS) convertServerHeaders()84 public Http2Headers convertServerHeaders() { 85 return Utils.convertServerHeaders(metadata); 86 } 87 88 /** 89 * This will encode the random metadata fields, and repeatedly lookup the default other headers. 90 */ 91 @Benchmark 92 @BenchmarkMode(Mode.SampleTime) 93 @OutputTimeUnit(TimeUnit.NANOSECONDS) encodeClientHeaders()94 public ByteBuf encodeClientHeaders() throws Exception { 95 scratchBuffer.clear(); 96 Http2Headers headers = 97 Utils.convertClientHeaders(metadata, scheme, defaultPath, authority, Utils.HTTP_METHOD, 98 userAgent); 99 headersEncoder.encodeHeaders(1, headers, scratchBuffer); 100 return scratchBuffer; 101 } 102 } 103