Skip to content

Commit

Permalink
Benchmarks (#292)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Brian Clozel <[email protected]>
  • Loading branch information
marcingrzejszczak and bclozel authored Jun 21, 2023
1 parent c8aebc8 commit 38fc7a9
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 2 deletions.
21 changes: 21 additions & 0 deletions benchmarks/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
dependencies {
jmh project(':micrometer-tracing-bridge-brave')
jmh project(':micrometer-tracing-bridge-otel')
jmh 'org.openjdk.jmh:jmh-core:latest.release'
jmh 'io.zipkin.brave:brave-tests'

jmh 'ch.qos.logback:logback-classic'

// Nebula doesn't like having jmhAnnotationProcessor without jmh so we just add it twice.
jmh 'org.openjdk.jmh:jmh-generator-annprocess:latest.release'
jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:latest.release'
}

jmh {
jmhVersion = '1.36'
fork = 1
warmupIterations = 1
iterations = 1
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
zip64 = true
}
1 change: 1 addition & 0 deletions benchmarks/src/jmh/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
generated
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright 2017 VMware, Inc.
*
* 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
*
* https://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.micrometer.benchmark.tracer;

import brave.Span;
import brave.Tracing;
import brave.handler.SpanHandler;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.propagation.TraceContextOrSamplingFlags;
import brave.sampler.Sampler;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext;
import io.micrometer.tracing.brave.bridge.BraveTracer;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

@BenchmarkMode(Mode.Throughput)
public class BraveTracerBenchmark implements MicrometerTracingBenchmarks {

@State(Scope.Benchmark)
public static class MicrometerTracingState {

@Param({ "5" })
public int childSpanCount;

ThreadLocalCurrentTraceContext braveCurrentTraceContext;

BraveCurrentTraceContext bridgeContext;

Tracing tracing;

brave.Tracer braveTracer;

Tracer tracer;

@Setup
public void setup() {
this.braveCurrentTraceContext = ThreadLocalCurrentTraceContext.newBuilder().build();
this.bridgeContext = new BraveCurrentTraceContext(this.braveCurrentTraceContext);
this.tracing = Tracing.newBuilder()
.currentTraceContext(this.braveCurrentTraceContext)
.sampler(Sampler.NEVER_SAMPLE)
.addSpanHandler(SpanHandler.NOOP)
.build();
this.tracing.setNoop(true);
this.braveTracer = this.tracing.tracer();
this.tracer = new BraveTracer(this.braveTracer, this.bridgeContext, new BraveBaggageManager());
}

@TearDown
public void close() {
this.tracing.close();
}

}

@Benchmark
public void micrometerTracing(MicrometerTracingState state, Blackhole blackhole) {
micrometerTracing(state.tracer, state.childSpanCount, blackhole);
}

@Benchmark
public io.micrometer.tracing.Span micrometerTracingNewSpan(MicrometerTracingState state) {
return micrometerTracingNewSpan(state.tracer);
}

@Benchmark
public void micrometerTracingWithScope(MicrometerTracingState state, Blackhole blackhole) {
micrometerTracingWithScope(state.tracer, state.childSpanCount, blackhole);
}

@State(Scope.Benchmark)
public static class BraveState {

@Param({ "5" })
public int childSpanCount;

ThreadLocalCurrentTraceContext braveCurrentTraceContext;

Tracing tracing;

brave.Tracer tracer;

@Setup
public void setup() {
this.braveCurrentTraceContext = ThreadLocalCurrentTraceContext.newBuilder().build();
this.tracing = Tracing.newBuilder()
.currentTraceContext(this.braveCurrentTraceContext)
.sampler(Sampler.NEVER_SAMPLE)
.addSpanHandler(SpanHandler.NOOP)
.build();
this.tracing.setNoop(true);
this.tracer = this.tracing.tracer();
}

@TearDown
public void close() {
this.tracing.close();
}

}

@Benchmark
public void braveTracing(BraveState state, Blackhole blackhole) {
brave.Span parentSpan = state.tracer.nextSpan().name("parent-span").start();
TraceContextOrSamplingFlags traceContext = TraceContextOrSamplingFlags.create(parentSpan.context());
for (int i = 0; i < state.childSpanCount; i++) {
brave.Span span = state.tracer.nextSpan(traceContext).name("new-span" + i);
span.start().tag("key", "value").annotate("event").finish();
blackhole.consume(span);
}
parentSpan.finish();
blackhole.consume(parentSpan);
}

@Benchmark
public Span braveTracingNewSpan(BraveState state, Blackhole blackhole) {
brave.Span span = state.tracer.nextSpan().name("child-span").start();
span.finish();
return span;
}

@Benchmark
public void braveTracingWithScope(BraveState state, Blackhole blackhole) {
brave.Span parentSpan = state.tracer.nextSpan().name("parent-span").start();
try (brave.Tracer.SpanInScope spanInScope = state.tracer.withSpanInScope(parentSpan)) {
for (int i = 0; i < state.childSpanCount; i++) {
brave.Span childSpan = state.tracer.nextSpan().name("new-span" + i);
try (brave.Tracer.SpanInScope spanInScope2 = state.tracer.withSpanInScope(childSpan.start())) {
childSpan.tag("key", "value").annotate("event");
}
childSpan.finish();
blackhole.consume(childSpan);
}
}
parentSpan.finish();
blackhole.consume(parentSpan);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2017 VMware, Inc.
*
* 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
*
* https://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.micrometer.benchmark.tracer;

import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import org.openjdk.jmh.infra.Blackhole;

interface MicrometerTracingBenchmarks {

default void micrometerTracing(Tracer tracer, int childSpanCount, Blackhole blackhole) {
Span parentSpan = tracer.nextSpan().name("parent-span").start();
for (int i = 0; i < childSpanCount; i++) {
Span span = tracer.nextSpan(parentSpan).name("new-span" + i);
span.start().tag("key", "value").event("event").end();
blackhole.consume(span);
}
parentSpan.end();
blackhole.consume(parentSpan);
}

default Span micrometerTracingNewSpan(Tracer tracer) {
Span span = tracer.nextSpan().name("child-span").start();
span.end();
return span;
}

default void micrometerTracingWithScope(Tracer tracer, int childSpanCount, Blackhole blackhole) {
Span parentSpan = tracer.nextSpan().name("parent-span").start();
try (Tracer.SpanInScope ws = tracer.withSpan(parentSpan)) {
for (int i = 0; i < childSpanCount; i++) {
Span childSpan = tracer.nextSpan().name("new-span" + i).start();
try (Tracer.SpanInScope ws2 = tracer.withSpan(childSpan)) {
childSpan.tag("key", "value").event("event");
}
childSpan.end();
}
}
parentSpan.end();
blackhole.consume(parentSpan);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright 2017 VMware, Inc.
*
* 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
*
* https://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.micrometer.benchmark.tracer;

import io.micrometer.tracing.Span;
import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
import io.micrometer.tracing.otel.bridge.OtelTracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.Collections;

@BenchmarkMode(Mode.Throughput)
public class OtelTracerBenchmark implements MicrometerTracingBenchmarks {

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(OtelTracerBenchmark.class.getSimpleName())
.warmupIterations(5)
.measurementIterations(10)
.mode(Mode.SampleTime)
.forks(1)
.build();

new Runner(opt).run();
}

@State(Scope.Benchmark)
public static class MicrometerTracingState {

@Param({ "5" })
public int childSpanCount;

SdkTracerProvider sdkTracerProvider;

OpenTelemetrySdk openTelemetrySdk;

io.opentelemetry.api.trace.Tracer otelTracer;

OtelCurrentTraceContext otelCurrentTraceContext;

OtelTracer tracer;

Span createdSpan;

Span startedSpan;

@Setup
public void setup() {
this.sdkTracerProvider = SdkTracerProvider.builder().setSampler(Sampler.alwaysOff()).build();
this.openTelemetrySdk = OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).build();
this.otelTracer = openTelemetrySdk.getTracerProvider().get("io.micrometer.micrometer-tracing");
this.otelCurrentTraceContext = new OtelCurrentTraceContext();
this.tracer = new OtelTracer(otelTracer, otelCurrentTraceContext, event -> {
}, new OtelBaggageManager(otelCurrentTraceContext, Collections.emptyList(), Collections.emptyList()));
this.createdSpan = this.tracer.nextSpan().name("created-span");
this.startedSpan = this.tracer.nextSpan().name("started-span").start();
}

}

@Benchmark
public void micrometerTracing(MicrometerTracingState state, Blackhole blackhole) {
micrometerTracing(state.tracer, state.childSpanCount, blackhole);
}

@Benchmark
public Span micrometerTracingNewSpan(MicrometerTracingState state) {
return micrometerTracingNewSpan(state.tracer);
}

@Benchmark
public void micrometerTracingWithScope(MicrometerTracingState state, Blackhole blackhole) {
micrometerTracingWithScope(state.tracer, state.childSpanCount, blackhole);
}

@State(Scope.Benchmark)
public static class OtelState {

@Param({ "5" })
public int childSpanCount;

SdkTracerProvider sdkTracerProvider;

OpenTelemetrySdk openTelemetrySdk;

io.opentelemetry.api.trace.Tracer tracer;

io.opentelemetry.api.trace.Span startedSpan;

Context parentContext;

@Setup
public void setup() {
this.sdkTracerProvider = SdkTracerProvider.builder().setSampler(Sampler.alwaysOff()).build();
this.openTelemetrySdk = OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).build();
this.tracer = openTelemetrySdk.getTracerProvider().get("io.micrometer.micrometer-tracing");
this.startedSpan = this.tracer.spanBuilder("started-span").startSpan();
this.parentContext = Context.root().with(this.startedSpan);
}

}

@Benchmark
public void otelTracing(OtelState state, Blackhole blackhole) {
io.opentelemetry.api.trace.Span parentSpan = state.tracer.spanBuilder("parent-span").startSpan();
for (int i = 0; i < state.childSpanCount; i++) {
io.opentelemetry.api.trace.Span span = state.tracer.spanBuilder("new-span" + i)
.setParent(state.parentContext)
.startSpan();
span.setAttribute("key", "value").addEvent("event").end();
blackhole.consume(span);
}
parentSpan.end();
blackhole.consume(parentSpan);
}

@Benchmark
public io.opentelemetry.api.trace.Span otelTracingNewSpan(OtelState state) {
io.opentelemetry.api.trace.Span parentSpan = state.tracer.spanBuilder("child-span").startSpan();
parentSpan.end();
return parentSpan;
}

@Benchmark
public void otelTracingWithScope(OtelState state, Blackhole blackhole) {
io.opentelemetry.api.trace.Span parentSpan = state.tracer.spanBuilder("parent-span").startSpan();
try (io.opentelemetry.context.Scope scope = parentSpan.makeCurrent()) {
for (int i = 0; i < state.childSpanCount; i++) {
io.opentelemetry.api.trace.Span span = state.tracer.spanBuilder("new-span" + i).startSpan();
try (io.opentelemetry.context.Scope scope2 = span.makeCurrent()) {
span.setAttribute("key", "value").addEvent("event");
}
span.end();
blackhole.consume(span);
}
}
parentSpan.end();
blackhole.consume(parentSpan);
}

}
Loading

0 comments on commit 38fc7a9

Please sign in to comment.