Skip to content

Instantly share code, notes, and snippets.

@danielmitterdorfer
Last active March 21, 2016 11:18
Show Gist options
  • Select an option

  • Save danielmitterdorfer/871cd62d7e16e45ae79d to your computer and use it in GitHub Desktop.

Select an option

Save danielmitterdorfer/871cd62d7e16e45ae79d to your computer and use it in GitHub Desktop.
RequestSizeLimitHandlerBenchmark
/*
* 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;
}
}
}
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
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
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