Skip to content

Commit

Permalink
Enhance benchmarks and fix performance issues
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimir-bukhtoyarov committed Oct 23, 2016
1 parent 4c2c774 commit 638889b
Show file tree
Hide file tree
Showing 9 changed files with 492 additions and 256 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
*
* Copyright 2016 Vladimir Bukhtoyarov
*
* 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
*
* http://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 com.github.metricscore.hdr.histogram;

import com.codahale.metrics.Snapshot;
import org.HdrHistogram.Histogram;
import org.openjdk.jmh.annotations.*;
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.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;


@BenchmarkMode({Mode.Throughput, Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class CountAtPercentileExtractionBenchmark {

@State(Scope.Benchmark)
public static class HistogramState {

Histogram histogram = new Histogram(1000, 3600L * 1_000_000_000L, 2);
static double[] DEFAULT_PERCENTILES_7 = new double[]{0.5, 0.75, 0.9, 0.95, 0.98, 0.99, 0.999};
static double[] DEFAULT_PERCENTILES_1 = new double[]{0.999};

@Setup
public void setup() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 1024; j++) {
// generate latency between 5ms and 20ms
long randomNanos = ThreadLocalRandom.current().nextLong(15_000_000) + 5_000_000;
histogram.recordValue(randomNanos);
}
}
}
}

@Benchmark
public Snapshot calculatePercentile_7(HistogramState state) {
return HdrReservoir.takeSmartSnapshot(HistogramState.DEFAULT_PERCENTILES_7, state.histogram);
}

@Benchmark
public Snapshot calculatePercentile_1(HistogramState state) {
return HdrReservoir.takeSmartSnapshot(HistogramState.DEFAULT_PERCENTILES_1, state.histogram);
}

public static class OneThread {
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(((Class) CountAtPercentileExtractionBenchmark.class).getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.threads(1)
.forks(1)
.build();
try {
new Runner(opt).run();
} catch (RunnerException e) {
throw new RuntimeException(e);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
*
* Copyright 2016 Vladimir Bukhtoyarov
*
* 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
*
* http://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 com.github.metricscore.hdr.histogram.accumulator;

import com.codahale.metrics.ExponentiallyDecayingReservoir;
import com.codahale.metrics.Histogram;
import com.github.metricscore.hdr.histogram.HdrBuilder;
import com.github.metricscore.hdr.histogram.OverflowResolver;
import org.openjdk.jmh.annotations.*;
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.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

@BenchmarkMode({Mode.Throughput, Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class HistogramRecordingBenchmark {

@State(Scope.Benchmark)
public static class HistogramState {

final Histogram chunkedHistogram = new HdrBuilder()
.resetReservoirPeriodicallyByChunks(Duration.ofSeconds(3), 3)
.buildHistogram();

final Histogram upperLimitedChunkedHistogram = new HdrBuilder()
.resetReservoirPeriodicallyByChunks(Duration.ofSeconds(3), 3)
.withLowestDiscernibleValue(TimeUnit.MICROSECONDS.toNanos(1))
.withHighestTrackableValue(TimeUnit.MINUTES.toNanos(5), OverflowResolver.REDUCE_TO_HIGHEST_TRACKABLE)
.buildHistogram();

final Histogram resetOnSnapshotHistogram = new HdrBuilder()
.resetReservoirOnSnapshot()
.withLowestDiscernibleValue(TimeUnit.MICROSECONDS.toNanos(1))
.withHighestTrackableValue(TimeUnit.MINUTES.toNanos(5), OverflowResolver.REDUCE_TO_HIGHEST_TRACKABLE)
.buildHistogram();

final Histogram resetPeriodicallyHistogram = new HdrBuilder()
.resetReservoirPeriodically(Duration.ofSeconds(300))
.withLowestDiscernibleValue(TimeUnit.MICROSECONDS.toNanos(1))
.withHighestTrackableValue(TimeUnit.MINUTES.toNanos(5), OverflowResolver.REDUCE_TO_HIGHEST_TRACKABLE)
.buildHistogram();

final Histogram uniformHistogram = new HdrBuilder()
.neverResetReservoir()
.withLowestDiscernibleValue(TimeUnit.MICROSECONDS.toNanos(1))
.withHighestTrackableValue(TimeUnit.MINUTES.toNanos(5), OverflowResolver.REDUCE_TO_HIGHEST_TRACKABLE)
.buildHistogram();

final Histogram metricsCoreHistogram = new Histogram(new ExponentiallyDecayingReservoir());

}

@Benchmark
public long baseLine() {
return getRandomValue();
}

@Benchmark
public void updateMetricsCoreHistogram(HistogramState state) {
state.metricsCoreHistogram.update(getRandomValue());
}

@Benchmark
public void updateUniformHistogram(HistogramState state) {
state.uniformHistogram.update(getRandomValue());
}

@Benchmark
public void updateResetPeriodicallyHistogram(HistogramState state) {
state.resetPeriodicallyHistogram.update(getRandomValue());
}

@Benchmark
public void updateResetOnSnapshotHistogram(HistogramState state) {
state.resetOnSnapshotHistogram.update(getRandomValue());
}

@Benchmark
public void updateChunkedHistogram(HistogramState state) {
state.chunkedHistogram.update(getRandomValue());
}

@Benchmark
public void updateChunkedUpperLimitedHistogram(HistogramState state) {
state.upperLimitedChunkedHistogram.update(getRandomValue());
}

private static long getRandomValue() {
return ThreadLocalRandom.current().nextLong(15_000_000) + 5_000_000;
}

public static class OneThread {
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(((Class) HistogramRecordingBenchmark.class).getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.threads(1)
.forks(1)
.build();
try {
new Runner(opt).run();
} catch (RunnerException e) {
throw new RuntimeException(e);
}
}
}

public static class FourThread {
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(((Class) HistogramRecordingBenchmark.class).getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.threads(4)
.forks(1)
.build();
try {
new Runner(opt).run();
} catch (RunnerException e) {
throw new RuntimeException(e);
}
}
}

}
Loading

0 comments on commit 638889b

Please sign in to comment.