diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 6d8c9c5c45..32170a40cb 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -19,12 +19,31 @@ 1.37 0.16.0 3.0.2 + + 1.66.0 true true + + + io.opentelemetry + opentelemetry-bom + ${benchmark.otel.version} + pom + import + + + io.opentelemetry + opentelemetry-bom-alpha + ${benchmark.otel.version}-alpha + pom + import + io.opentelemetry.instrumentation opentelemetry-instrumentation-bom-alpha @@ -73,6 +92,10 @@ io.opentelemetry opentelemetry-sdk-testing + + io.opentelemetry + opentelemetry-api-incubator + ${project.artifactId} diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index d8b75e437c..2b612a7f24 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -3,10 +3,15 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.BoundDoubleCounter; +import io.opentelemetry.api.incubator.metrics.BoundLongCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.metrics.ExemplarFilter; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; @@ -94,6 +99,7 @@ public OpenTelemetryCounter() { SdkMeterProvider.builder() .registerMetricReader(InMemoryMetricReader.create()) .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) .build(); OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); @@ -111,6 +117,45 @@ public OpenTelemetryCounter() { } } + /** + * OpenTelemetry counter using the incubator "bound instrument" API, which pre-binds a set of + * attributes at initialization time to avoid a per-record attribute map lookup. + */ + @State(Scope.Benchmark) + public static class OpenTelemetryBoundCounter { + + final BoundLongCounter longCounter; + final BoundDoubleCounter doubleCounter; + + public OpenTelemetryBoundCounter() { + + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) + .build(); + OpenTelemetry openTelemetry = + OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Meter meter = + openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + Attributes attributes = + Attributes.of( + AttributeKey.stringKey("path"), "/", + AttributeKey.stringKey("status"), "200"); + this.longCounter = + ((ExtendedLongCounter) meter.counterBuilder("test1").setDescription("test").build()) + .bind(attributes); + this.doubleCounter = + ((ExtendedDoubleCounter) + meter.counterBuilder("test2").ofDoubles().setDescription("test").build()) + .bind(attributes); + } + } + @Benchmark @Threads(4) public CounterDataPoint prometheusAdd(RandomNumbers randomNumbers, PrometheusCounter counter) { @@ -156,6 +201,25 @@ public LongCounter openTelemetryIncNoLabels(OpenTelemetryCounter counter) { return counter.longCounter; } + @Benchmark + @Threads(4) + public BoundDoubleCounter openTelemetryBoundAdd( + RandomNumbers randomNumbers, OpenTelemetryBoundCounter counter) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + counter.doubleCounter.add(randomNumbers.randomNumbers[i]); + } + return counter.doubleCounter; + } + + @Benchmark + @Threads(4) + public BoundLongCounter openTelemetryBoundInc(OpenTelemetryBoundCounter counter) { + for (int i = 0; i < 10 * 1024; i++) { + counter.longCounter.add(1); + } + return counter.longCounter; + } + @Benchmark @Threads(4) public io.prometheus.client.Counter.Child simpleclientAdd( diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java index 41b7097dbc..3878568925 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java @@ -1,9 +1,14 @@ package io.prometheus.metrics.benchmarks; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.BoundDoubleHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.ExemplarFilter; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.View; @@ -95,6 +100,7 @@ public OpenTelemetryClassicHistogram() { SdkMeterProvider.builder() .registerMetricReader(InMemoryMetricReader.create()) .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) .registerView( InstrumentSelector.builder().setName("test").build(), View.builder() @@ -126,6 +132,7 @@ public OpenTelemetryExponentialHistogram() { SdkMeterProvider.builder() .registerMetricReader(InMemoryMetricReader.create()) .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) .registerView( InstrumentSelector.builder().setName("test").build(), View.builder() @@ -143,6 +150,85 @@ public OpenTelemetryExponentialHistogram() { } } + /** + * OpenTelemetry classic histogram using the incubator "bound instrument" API to pre-bind + * attributes at initialization time. + */ + @State(Scope.Benchmark) + public static class OpenTelemetryBoundClassicHistogram { + + final BoundDoubleHistogram histogram; + + public OpenTelemetryBoundClassicHistogram() { + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) + .registerView( + InstrumentSelector.builder().setName("test").build(), + View.builder() + .setAggregation( + Aggregation.explicitBucketHistogram( + Arrays.asList( + .005, .01, .025, .05, .1, .25, .5, 1.0, 2.5, 5.0, 10.0))) + .build()) + .build(); + OpenTelemetry openTelemetry = + OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Meter meter = + openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + Attributes attributes = + Attributes.of( + AttributeKey.stringKey("path"), "/", + AttributeKey.stringKey("status"), "200"); + this.histogram = + ((ExtendedDoubleHistogram) meter.histogramBuilder("test").setDescription("test").build()) + .bind(attributes); + } + } + + /** + * OpenTelemetry exponential histogram using the incubator "bound instrument" API to pre-bind + * attributes at initialization time. + */ + @State(Scope.Benchmark) + public static class OpenTelemetryBoundExponentialHistogram { + + final BoundDoubleHistogram histogram; + + public OpenTelemetryBoundExponentialHistogram() { + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .setExemplarFilter(ExemplarFilter.alwaysOff()) + .registerView( + InstrumentSelector.builder().setName("test").build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram(10_000, 5)) + .build()) + .build(); + OpenTelemetry openTelemetry = + OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Meter meter = + openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + Attributes attributes = + Attributes.of( + AttributeKey.stringKey("path"), "/", + AttributeKey.stringKey("status"), "200"); + this.histogram = + ((ExtendedDoubleHistogram) meter.histogramBuilder("test").setDescription("test").build()) + .bind(attributes); + } + } + @Benchmark @Threads(4) public Histogram prometheusClassic( @@ -212,4 +298,24 @@ public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryExponential( } return histogram.histogram; } + + @Benchmark + @Threads(4) + public BoundDoubleHistogram openTelemetryBoundClassic( + RandomNumbers randomNumbers, OpenTelemetryBoundClassicHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.histogram.record(randomNumbers.randomNumbers[i]); + } + return histogram.histogram; + } + + @Benchmark + @Threads(4) + public BoundDoubleHistogram openTelemetryBoundExponential( + RandomNumbers randomNumbers, OpenTelemetryBoundExponentialHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.histogram.record(randomNumbers.randomNumbers[i]); + } + return histogram.histogram; + } }