Cache ImmutableKeyValuePairs#hashCode (#5307)

This commit is contained in:
jack-berg 2023-03-18 13:31:58 -05:00 committed by GitHub
parent 7f9c0ddcd9
commit 3581d6e642
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 3 deletions

View File

@ -25,11 +25,30 @@ public class AttributesBenchmark {
// pre-allocate the keys & values to remove one possible confounding factor
private static final List<AttributeKey<String>> keys = new ArrayList<>(10);
private static final List<String> values = new ArrayList<>(10);
private static final List<Attributes> attributes = new ArrayList<>();
static {
for (int i = 0; i < 10; i++) {
keys.add(AttributeKey.stringKey("key" + i));
values.add("value" + i);
AttributesBuilder builder = Attributes.builder();
for (int j = 0; j <= i; j++) {
builder.put(keys.get(j), values.get(j));
}
attributes.add(builder.build());
}
}
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@Fork(1)
@Measurement(iterations = 15, time = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@SuppressWarnings("ReturnValueIgnored")
public void computeHashCode() {
for (Attributes attributes : attributes) {
attributes.hashCode();
}
}

View File

@ -32,6 +32,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable
public abstract class ImmutableKeyValuePairs<K, V> {
private final Object[] data;
private int hashcode;
/**
* Stores the raw object data directly. Does not do any de-duping or sorting. If you use this
@ -247,9 +248,13 @@ public abstract class ImmutableKeyValuePairs<K, V> {
@Override
public int hashCode() {
int result = 1;
result *= 1000003;
result ^= Arrays.hashCode(data);
int result = hashcode;
if (result == 0) {
result = 1;
result *= 1000003;
result ^= Arrays.hashCode(data);
hashcode = result;
}
return result;
}

View File

@ -6,9 +6,12 @@
package io.opentelemetry.sdk.metrics;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@ -32,6 +35,22 @@ import org.openjdk.jmh.infra.ThreadParams;
@Fork(1)
public class MetricsBenchmarks {
private static final List<Attributes> ATTRIBUTES_LIST;
static {
int keys = 5;
int valuesPerKey = 20;
ATTRIBUTES_LIST = new ArrayList<>();
for (int key = 0; key < keys; key++) {
AttributesBuilder builder = Attributes.builder();
for (int value = 0; value < valuesPerKey; value++) {
builder.put("key_" + key, "value_" + value);
}
ATTRIBUTES_LIST.add(builder.build());
}
}
@State(Scope.Thread)
public static class ThreadState {
@ -65,6 +84,14 @@ public class MetricsBenchmarks {
}
}
@Benchmark
@Threads(1)
public void recordToMultipleAttributes(ThreadState threadState) {
for (Attributes attributes : ATTRIBUTES_LIST) {
threadState.op.perform(attributes);
}
}
@Benchmark
@Threads(1)
public void oneThread(ThreadState threadState) {