From ff85102a46da8c63b511bb7b8b2b88a52b57028a Mon Sep 17 00:00:00 2001 From: Nikita Salnikov-Tarnovski Date: Thu, 3 Jun 2021 02:57:16 +0300 Subject: [PATCH] Remove unnecessary string allocation on hot path (#3272) --- .../api/trace/SpanIdBenchmark.java | 33 +++++++++++++++++++ .../api/internal/OtelEncodingUtils.java | 4 +-- .../io/opentelemetry/api/internal/Utils.java | 14 ++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 api/all/src/jmh/java/io/opentelemetry/api/trace/SpanIdBenchmark.java diff --git a/api/all/src/jmh/java/io/opentelemetry/api/trace/SpanIdBenchmark.java b/api/all/src/jmh/java/io/opentelemetry/api/trace/SpanIdBenchmark.java new file mode 100644 index 0000000000..975cb0c157 --- /dev/null +++ b/api/all/src/jmh/java/io/opentelemetry/api/trace/SpanIdBenchmark.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.trace; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 15, time = 1) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(1) +@Threads(1) +public class SpanIdBenchmark { + + @Benchmark + public byte[] getSpanIdBytes() { + return SpanContext.getInvalid().getSpanIdBytes(); + } +} diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java index 914fe76245..e4203d5228 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java @@ -111,9 +111,9 @@ public final class OtelEncodingUtils { */ public static byte byteFromBase16(char first, char second) { Utils.checkArgument( - first < ASCII_CHARACTERS && DECODING[first] != -1, "invalid character " + first); + first < ASCII_CHARACTERS && DECODING[first] != -1, () -> "invalid character " + first); Utils.checkArgument( - second < ASCII_CHARACTERS && DECODING[second] != -1, "invalid character " + second); + second < ASCII_CHARACTERS && DECODING[second] != -1, () -> "invalid character " + second); int decoded = DECODING[first] << 4 | DECODING[second]; return (byte) decoded; } diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/Utils.java b/api/all/src/main/java/io/opentelemetry/api/internal/Utils.java index 2f6603e0da..5fda975b43 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/Utils.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/Utils.java @@ -5,6 +5,7 @@ package io.opentelemetry.api.internal; +import java.util.function.Supplier; import javax.annotation.concurrent.Immutable; /** General internal utility methods. */ @@ -25,4 +26,17 @@ public final class Utils { throw new IllegalArgumentException(errorMessage); } } + + /** + * Throws an {@link IllegalArgumentException} if the argument is false. This method is similar to + * {@code Preconditions.checkArgument(boolean, Object)} from Guava. + * + * @param isValid whether the argument check passed. + * @param errorMessage the supplier of the message to use for the exception. + */ + public static void checkArgument(boolean isValid, Supplier errorMessage) { + if (!isValid) { + throw new IllegalArgumentException(errorMessage.get()); + } + } }