Last active
March 21, 2016 11:18
-
-
Save danielmitterdorfer/871cd62d7e16e45ae79d to your computer and use it in GitHub Desktop.
RequestSizeLimitHandlerBenchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Licensed to Elasticsearch under one or more contributor | |
| * license agreements. See the NOTICE file distributed with | |
| * this work for additional information regarding copyright | |
| * ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.benchmarks; | |
| import org.elasticsearch.common.limit.CountingLimiter; | |
| import org.elasticsearch.common.unit.ByteSizeUnit; | |
| import org.elasticsearch.common.unit.ByteSizeValue; | |
| import org.elasticsearch.http.netty.RequestSizeLimitHandler; | |
| import org.elasticsearch.http.netty.pipelining.OrderedDownstreamChannelEvent; | |
| import org.elasticsearch.http.netty.pipelining.OrderedUpstreamMessageEvent; | |
| import org.jboss.netty.buffer.ChannelBuffers; | |
| import org.jboss.netty.channel.Channel; | |
| import org.jboss.netty.channel.ChannelConfig; | |
| import org.jboss.netty.channel.ChannelEvent; | |
| import org.jboss.netty.channel.ChannelFactory; | |
| import org.jboss.netty.channel.ChannelFuture; | |
| import org.jboss.netty.channel.ChannelHandler; | |
| import org.jboss.netty.channel.ChannelHandlerContext; | |
| import org.jboss.netty.channel.ChannelPipeline; | |
| import org.jboss.netty.channel.DownstreamMessageEvent; | |
| import org.jboss.netty.channel.SucceededChannelFuture; | |
| import org.jboss.netty.channel.UpstreamMessageEvent; | |
| import org.jboss.netty.channel.local.LocalAddress; | |
| import org.jboss.netty.handler.codec.http.DefaultHttpRequest; | |
| import org.jboss.netty.handler.codec.http.DefaultHttpResponse; | |
| import org.jboss.netty.handler.codec.http.HttpMethod; | |
| import org.jboss.netty.handler.codec.http.HttpResponseStatus; | |
| import org.jboss.netty.handler.codec.http.HttpVersion; | |
| import org.openjdk.jmh.annotations.Benchmark; | |
| import org.openjdk.jmh.annotations.BenchmarkMode; | |
| import org.openjdk.jmh.annotations.Fork; | |
| import org.openjdk.jmh.annotations.Mode; | |
| import org.openjdk.jmh.annotations.OperationsPerInvocation; | |
| import org.openjdk.jmh.annotations.OutputTimeUnit; | |
| import org.openjdk.jmh.annotations.Scope; | |
| import org.openjdk.jmh.annotations.Setup; | |
| import org.openjdk.jmh.annotations.State; | |
| import org.openjdk.jmh.infra.Blackhole; | |
| import java.net.SocketAddress; | |
| import java.nio.charset.StandardCharsets; | |
| import java.util.concurrent.TimeUnit; | |
| // invoke with java -jar build/libs/elasticsearch-microbenchmarks-0.1.0-all.jar ".*Request.*" -prof gc | |
| @Fork(2) | |
| @BenchmarkMode(Mode.AverageTime) | |
| @OutputTimeUnit(TimeUnit.MICROSECONDS) | |
| @State(Scope.Benchmark) | |
| public class RequestSizeLimitHandlerBenchmark { | |
| private static final String MATCH_ALL_QUERY = "{ \"match_all\": {} }"; | |
| private final LocalAddress remoteAddress = new LocalAddress(LocalAddress.EPHEMERAL); | |
| private RequestSizeLimitHandler handler; | |
| private UpstreamMessageEvent upstreamEvent; | |
| private DownstreamMessageEvent downstreamEvent; | |
| private TestChannelHandlerContext ctx; | |
| private TestChannelHandlerContext pipelineCtx; | |
| private OrderedDownstreamChannelEvent pipelineDownstreamEvent; | |
| private OrderedUpstreamMessageEvent pipelineUpstreamEvent; | |
| @Setup | |
| public void setup() { | |
| CountingLimiter limiter = new CountingLimiter(new ByteSizeValue(512, ByteSizeUnit.KB), "HTTP incoming"); | |
| handler = new RequestSizeLimitHandler(limiter); | |
| TestChannel channel = TestChannel.withId(5); | |
| TestChannel pipelineChannel = TestChannel.withId(6); | |
| ctx = new TestChannelHandlerContext(channel); | |
| pipelineCtx = new TestChannelHandlerContext(pipelineChannel); | |
| upstreamEvent = new UpstreamMessageEvent(channel, matchAllRequest(), remoteAddress); | |
| downstreamEvent = new DownstreamMessageEvent(channel, | |
| new SucceededChannelFuture(channel), emptyOkResponse(), remoteAddress); | |
| pipelineUpstreamEvent = new OrderedUpstreamMessageEvent(0, pipelineChannel, matchAllRequest(), remoteAddress); | |
| pipelineDownstreamEvent = new OrderedDownstreamChannelEvent(pipelineUpstreamEvent, emptyOkResponse()); | |
| } | |
| // do the same amount of work in both benchmark methods | |
| @Benchmark | |
| @OperationsPerInvocation(2) | |
| public void measureUpstreamDownstream(Blackhole bh) throws Exception { | |
| ctx.blackhole(bh); | |
| // note that it is tricky benchmarking void methods (due to dead code elimination) | |
| // we have taken extra care and verified against a version of the handler that returns | |
| // the reservation object that we're not prone to this problem with our use of blackhole | |
| // in this implementation. | |
| handler.handleUpstream(ctx, upstreamEvent); | |
| handler.handleDownstream(ctx, downstreamEvent); | |
| handler.handleUpstream(ctx, upstreamEvent); | |
| handler.handleDownstream(ctx, downstreamEvent); | |
| } | |
| @Benchmark | |
| @OperationsPerInvocation(2) | |
| public void measureMixedUpstreamDownstream(Blackhole bh) throws Exception { | |
| ctx.blackhole(bh); | |
| pipelineCtx.blackhole(bh); | |
| handler.handleUpstream(ctx, upstreamEvent); | |
| handler.handleUpstream(pipelineCtx, pipelineUpstreamEvent); | |
| handler.handleDownstream(pipelineCtx, pipelineDownstreamEvent); | |
| handler.handleDownstream(ctx, downstreamEvent); | |
| } | |
| @Benchmark | |
| @OperationsPerInvocation(2) | |
| public void measurePipelineUpstreamDownstream(Blackhole bh) throws Exception { | |
| pipelineCtx.blackhole(bh); | |
| handler.handleUpstream(pipelineCtx, pipelineUpstreamEvent); | |
| handler.handleDownstream(pipelineCtx, pipelineDownstreamEvent); | |
| handler.handleUpstream(pipelineCtx, pipelineUpstreamEvent); | |
| handler.handleDownstream(pipelineCtx, pipelineDownstreamEvent); | |
| } | |
| private DefaultHttpRequest matchAllRequest() { | |
| DefaultHttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/_search"); | |
| request.setContent(ChannelBuffers.wrappedBuffer(MATCH_ALL_QUERY.getBytes(StandardCharsets.UTF_8))); | |
| return request; | |
| } | |
| private DefaultHttpResponse emptyOkResponse() { | |
| return new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); | |
| } | |
| private static class TestChannelHandlerContext implements ChannelHandlerContext { | |
| private final Channel channel; | |
| private Blackhole blackhole; | |
| private TestChannelHandlerContext(Channel channel) { | |
| this.channel = channel; | |
| } | |
| public void blackhole(Blackhole blackhole) { | |
| this.blackhole = blackhole; | |
| } | |
| @Override | |
| public Channel getChannel() { | |
| return channel; | |
| } | |
| @Override | |
| public ChannelPipeline getPipeline() { | |
| return null; | |
| } | |
| @Override | |
| public String getName() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelHandler getHandler() { | |
| return null; | |
| } | |
| @Override | |
| public boolean canHandleUpstream() { | |
| return false; | |
| } | |
| @Override | |
| public boolean canHandleDownstream() { | |
| return false; | |
| } | |
| @Override | |
| public void sendUpstream(ChannelEvent e) { | |
| blackhole.consume(e); | |
| } | |
| @Override | |
| public void sendDownstream(ChannelEvent e) { | |
| blackhole.consume(e); | |
| } | |
| @Override | |
| public Object getAttachment() { | |
| return null; | |
| } | |
| @Override | |
| public void setAttachment(Object attachment) { | |
| } | |
| } | |
| private static class TestChannel implements Channel { | |
| private final Integer id; | |
| public static TestChannel withId(Integer id) { | |
| return new TestChannel(id); | |
| } | |
| private TestChannel(Integer id) { | |
| this.id = id; | |
| } | |
| @Override | |
| public Integer getId() { | |
| return id; | |
| } | |
| @Override | |
| public ChannelFactory getFactory() { | |
| return null; | |
| } | |
| @Override | |
| public Channel getParent() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelConfig getConfig() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelPipeline getPipeline() { | |
| return null; | |
| } | |
| @Override | |
| public boolean isOpen() { | |
| return false; | |
| } | |
| @Override | |
| public boolean isBound() { | |
| return false; | |
| } | |
| @Override | |
| public boolean isConnected() { | |
| return false; | |
| } | |
| @Override | |
| public SocketAddress getLocalAddress() { | |
| return null; | |
| } | |
| @Override | |
| public SocketAddress getRemoteAddress() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture write(Object message) { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture write(Object message, SocketAddress remoteAddress) { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture bind(SocketAddress localAddress) { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture connect(SocketAddress remoteAddress) { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture disconnect() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture unbind() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture close() { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture getCloseFuture() { | |
| return null; | |
| } | |
| @Override | |
| public int getInterestOps() { | |
| return 0; | |
| } | |
| @Override | |
| public boolean isReadable() { | |
| return false; | |
| } | |
| @Override | |
| public boolean isWritable() { | |
| return false; | |
| } | |
| @Override | |
| public ChannelFuture setInterestOps(int interestOps) { | |
| return null; | |
| } | |
| @Override | |
| public ChannelFuture setReadable(boolean readable) { | |
| return null; | |
| } | |
| @Override | |
| public boolean getUserDefinedWritability(int index) { | |
| return false; | |
| } | |
| @Override | |
| public void setUserDefinedWritability(int index, boolean isWritable) { | |
| } | |
| @Override | |
| public Object getAttachment() { | |
| return null; | |
| } | |
| @Override | |
| public void setAttachment(Object attachment) { | |
| } | |
| @Override | |
| public int compareTo(Channel o) { | |
| return 0; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Benchmark Mode Cnt Score Error Units | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream avgt 40 0.112 ± 0.001 us/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.alloc.rate avgt 40 888.597 ± 5.311 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.alloc.rate.norm avgt 40 104.000 ± 0.001 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 886.906 ± 13.913 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 103.797 ± 1.378 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.283 ± 0.042 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.033 ± 0.005 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.count avgt 40 805.000 counts | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.time avgt 40 374.000 ms | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream avgt 40 0.119 ± 0.001 us/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.alloc.rate avgt 40 643.588 ± 7.813 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.alloc.rate.norm avgt 40 80.000 ± 0.001 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 641.167 ± 11.763 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 79.703 ± 1.186 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.263 ± 0.047 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.033 ± 0.006 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.count avgt 40 730.000 counts | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.time avgt 40 355.000 ms | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream avgt 40 0.094 ± 0.006 us/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.alloc.rate avgt 40 929.838 ± 30.655 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.alloc.rate.norm avgt 40 92.000 ± 6.837 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 930.778 ± 34.384 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 92.079 ± 6.949 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.256 ± 0.037 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.025 ± 0.004 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.count avgt 40 686.000 counts | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.time avgt 40 355.000 ms |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Benchmark Mode Cnt Score Error Units | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream avgt 40 0.095 ± 0.002 us/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.alloc.rate avgt 40 565.542 ± 10.487 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.alloc.rate.norm avgt 40 56.000 ± 0.001 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 565.259 ± 11.664 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 55.977 ± 0.655 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.254 ± 0.042 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.025 ± 0.004 B/op | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.count avgt 40 631.000 counts | |
| RequestSizeLimitHandlerBenchmark.measureMixedUpstreamDownstream:·gc.time avgt 40 327.000 ms | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream avgt 40 0.104 ± 0.001 us/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.alloc.rate avgt 40 514.703 ± 2.546 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.alloc.rate.norm avgt 40 56.000 ± 0.001 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 511.496 ± 6.657 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 55.653 ± 0.719 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.232 ± 0.038 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.025 ± 0.004 B/op | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.count avgt 40 678.000 counts | |
| RequestSizeLimitHandlerBenchmark.measurePipelineUpstreamDownstream:·gc.time avgt 40 323.000 ms | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream avgt 40 0.079 ± 0.003 us/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.alloc.rate avgt 40 681.076 ± 22.811 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.alloc.rate.norm avgt 40 56.000 ± 0.001 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Eden_Space avgt 40 678.555 ± 26.725 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Eden_Space.norm avgt 40 55.794 ± 1.230 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Survivor_Space avgt 40 0.240 ± 0.047 MB/sec | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.churn.PS_Survivor_Space.norm avgt 40 0.020 ± 0.004 B/op | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.count avgt 40 650.000 counts | |
| RequestSizeLimitHandlerBenchmark.measureUpstreamDownstream:·gc.time avgt 40 337.000 ms |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Darwin io 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment