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;
+ }
}