From f9832ee7f0b30e45b790a85b4967d6bc88c4afb2 Mon Sep 17 00:00:00 2001 From: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:49:37 +0900 Subject: [PATCH] Add benchmarks for DefaultLTT start/stop Start and stop are called on the critical path. We should have benchmarks for them to evaluate changes that may affect their performance. --- .../core/DefaultLongTaskTimerBenchmark.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 benchmarks/benchmarks-core/src/jmh/java/io/micrometer/benchmark/core/DefaultLongTaskTimerBenchmark.java diff --git a/benchmarks/benchmarks-core/src/jmh/java/io/micrometer/benchmark/core/DefaultLongTaskTimerBenchmark.java b/benchmarks/benchmarks-core/src/jmh/java/io/micrometer/benchmark/core/DefaultLongTaskTimerBenchmark.java new file mode 100644 index 0000000000..7fe8b81775 --- /dev/null +++ b/benchmarks/benchmarks-core/src/jmh/java/io/micrometer/benchmark/core/DefaultLongTaskTimerBenchmark.java @@ -0,0 +1,96 @@ +/* + * Copyright 2024 VMware, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micrometer.benchmark.core; + +import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; +import io.micrometer.core.instrument.internal.DefaultLongTaskTimer; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + +@State(Scope.Benchmark) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Fork(1) +public class DefaultLongTaskTimerBenchmark { + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder().include(DefaultLongTaskTimerBenchmark.class.getSimpleName()).build(); + + new Runner(opt).run(); + } + + private static final int sampleCount = 10_000; + + private MockClock clock; + + private DefaultLongTaskTimer longTaskTimer; + + private LongTaskTimer.Sample middleSample; + + @Setup(Level.Invocation) + public void setup() { + clock = new MockClock(); + longTaskTimer = new DefaultLongTaskTimer( + new Meter.Id("ltt", Tags.empty(), TimeUnit.MILLISECONDS.toString().toLowerCase(), null, + Meter.Type.LONG_TASK_TIMER), + clock, TimeUnit.MILLISECONDS, DistributionStatisticConfig.DEFAULT, false); + // start some samples for benchmarking start/stop with active samples + IntStream.range(0, sampleCount).forEach(offset -> { + clock.add(offset, TimeUnit.MILLISECONDS); + LongTaskTimer.Sample sample = longTaskTimer.start(); + if (offset == sampleCount / 2) + middleSample = sample; + }); + } + + @TearDown(Level.Invocation) + public void tearDown() { + longTaskTimer = null; + } + + @Benchmark + @Warmup(iterations = 20) + @Measurement(iterations = 200) + @BenchmarkMode(Mode.SingleShotTime) + public LongTaskTimer.Sample start() { + return longTaskTimer.start(); + } + + @Benchmark + @Warmup(iterations = 20) + @Measurement(iterations = 200) + @BenchmarkMode(Mode.SingleShotTime) + public long stop() { + return middleSample.stop(); + } + + @Benchmark + @Warmup(iterations = 20) + @Measurement(iterations = 200) + @BenchmarkMode(Mode.SingleShotTime) + public long startAndStop() { + start(); + return stop(); + } + +}