Skip to content

Commit

Permalink
Add ExponentialHistogramIndexerBenchmark (#4989)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg committed Dec 1, 2022
1 parent 14b64fc commit e732328
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 7 deletions.
@@ -0,0 +1,64 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.metrics.internal.aggregator;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

/** Measures runtime cost of computing bucket indexes for exponential histograms. */
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Measurement(iterations = 5, time = 1)
@Warmup(iterations = 5, time = 1)
@Fork(1)
public class ExponentialHistogramIndexerBenchmark {

@State(Scope.Thread)
public static class ThreadState {
@Param(value = {"1", "0", "-1"})
int scale;

private double[] values;
private final AtomicLong valueIndex = new AtomicLong();
private ExponentialHistogramIndexer indexer;

@Setup(Level.Trial)
public final void setup() {
Random random = new Random();
int numValues = 2000;
values = new double[numValues];
for (int i = 0; i < numValues; i++) {
values[i] = random.nextDouble() * 1000;
}
indexer = ExponentialHistogramIndexer.get(scale);
}

public void compute() {
// Compute a number of samples
for (int i = 0; i < 2000; i++) {
indexer.computeIndex(values[(int) (valueIndex.incrementAndGet() % values.length)]);
}
}
}

@Benchmark
public void computeIndex(ThreadState threadState) {
threadState.compute();
}
}
Expand Up @@ -25,16 +25,16 @@ public enum HistogramAggregationParam {
new DoubleExponentialHistogramAggregator(
ExemplarReservoir::doubleNoSamples,
ExponentialBucketStrategy.newStrategy(
20, ExponentialCounterFactory.circularBufferCounter()))),
20, ExponentialCounterFactory.circularBufferCounter(), 0))),
EXPONENTIAL_CIRCULAR_BUFFER(
new DoubleExponentialHistogramAggregator(
ExemplarReservoir::doubleNoSamples,
ExponentialBucketStrategy.newStrategy(
160, ExponentialCounterFactory.circularBufferCounter()))),
160, ExponentialCounterFactory.circularBufferCounter(), 0))),
EXPONENTIAL_MAP_COUNTER(
new DoubleExponentialHistogramAggregator(
ExemplarReservoir::doubleNoSamples,
ExponentialBucketStrategy.newStrategy(160, ExponentialCounterFactory.mapCounter())));
ExponentialBucketStrategy.newStrategy(160, ExponentialCounterFactory.mapCounter(), 0)));

private final Aggregator<?, ?> aggregator;

Expand Down
Expand Up @@ -10,26 +10,35 @@
/** The configuration for how to create exponential histogram buckets. */
final class ExponentialBucketStrategy {

private static final int STARTING_SCALE = 20;
private static final int DEFAULT_STARTING_SCALE = 20;

private final int startingScale;
/** The maximum number of buckets that will be used for positive or negative recordings. */
private final int maxBuckets;
/** The mechanism of constructing and copying buckets. */
private final ExponentialCounterFactory counterFactory;

private ExponentialBucketStrategy(int maxBuckets, ExponentialCounterFactory counterFactory) {
private ExponentialBucketStrategy(
int startingScale, int maxBuckets, ExponentialCounterFactory counterFactory) {
this.startingScale = startingScale;
this.maxBuckets = maxBuckets;
this.counterFactory = counterFactory;
}

/** Constructs fresh new buckets with default settings. */
DoubleExponentialHistogramBuckets newBuckets() {
return new DoubleExponentialHistogramBuckets(STARTING_SCALE, maxBuckets, counterFactory);
return new DoubleExponentialHistogramBuckets(startingScale, maxBuckets, counterFactory);
}

/** Create a new strategy for generating Exponential Buckets. */
static ExponentialBucketStrategy newStrategy(
int maxBuckets, ExponentialCounterFactory counterFactory) {
return new ExponentialBucketStrategy(maxBuckets, counterFactory);
return new ExponentialBucketStrategy(DEFAULT_STARTING_SCALE, maxBuckets, counterFactory);
}

/** Create a new strategy for generating Exponential Buckets. */
static ExponentialBucketStrategy newStrategy(
int maxBuckets, ExponentialCounterFactory counterFactory, int startingScale) {
return new ExponentialBucketStrategy(startingScale, maxBuckets, counterFactory);
}
}

0 comments on commit e732328

Please sign in to comment.