diff --git a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java index 0f36212b5..21c9bc0ce 100644 --- a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java @@ -8,7 +8,10 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; import java.util.concurrent.TimeUnit; public class CKMSQuantileBenchmark { @@ -18,79 +21,102 @@ public static class EmptyBenchmarkState { @Param({"10000", "100000", "1000000"}) public int value; - CKMSQuantiles ckmsQuantiles; - List quantiles; Random rand = new Random(0); - long[] shuffle; + List shuffle; + + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); @Setup(Level.Trial) public void setup() { quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.050)); - quantiles.add(new Quantile(0.90, 0.010)); - quantiles.add(new Quantile(0.95, 0.005)); - quantiles.add(new Quantile(0.99, 0.001)); - - - shuffle = new long[value]; - for (int i = 0; i < shuffle.length; i++) { - shuffle[i] = i; + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); } - Collections.shuffle(Arrays.asList(shuffle), rand); - + Collections.shuffle(shuffle, rand); } } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.MILLISECONDS) - public void ckmsQuantileInsertBenchmark(Blackhole blackhole, EmptyBenchmarkState state) { + public void ckmsQuantileInsertBenchmark(EmptyBenchmarkState state) { CKMSQuantiles q = new CKMSQuantiles(state.quantiles.toArray(new Quantile[]{})); - for (long l : state.shuffle) { + for (Double l : state.shuffle) { q.insert(l); } } + /** prefilled benchmark, means that we already have a filled and compressed samples available */ @State(Scope.Benchmark) public static class PrefilledBenchmarkState { - public int value = 1000000; + @Param({"10000", "100000", "1000000"}) + public int value; + CKMSQuantiles ckmsQuantiles; List quantiles; Random rand = new Random(0); - long[] shuffle; + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); + List shuffle; + + int rank = (int) (value * q95.quantile); + @Setup(Level.Trial) public void setup() { quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.050)); - quantiles.add(new Quantile(0.90, 0.010)); - quantiles.add(new Quantile(0.95, 0.005)); - quantiles.add(new Quantile(0.99, 0.001)); + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); + } + Collections.shuffle(shuffle, rand); - shuffle = new long[value]; - for (int i = 0; i < shuffle.length; i++) { - shuffle[i] = i; - } - Collections.shuffle(Arrays.asList(shuffle), rand); ckmsQuantiles = new CKMSQuantiles(quantiles.toArray(new Quantile[]{})); - for (long l : shuffle) { + for (Double l : shuffle) { ckmsQuantiles.insert(l); } - + System.out.println("Sample size is: " + ckmsQuantiles.samples.size()); } + } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void ckmsQuantileGetBenchmark(Blackhole blackhole, PrefilledBenchmarkState state) { - blackhole.consume(state.ckmsQuantiles.get(0.95)); + blackhole.consume(state.ckmsQuantiles.get(state.q90.quantile)); + } + + /** + * benchmark for the f method. + */ + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void ckmsQuantileF(Blackhole blackhole, PrefilledBenchmarkState state) { + blackhole.consume(state.ckmsQuantiles.f(state.rank)); } public static void main(String[] args) throws RunnerException { diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index ff75d6f4d..4d7d0f8bd 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -185,9 +185,9 @@ int f(int r) { // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. // To avoid running into these types of error we add 0.00000000001 before rounding down. if (r >= q.quantile * n) { - result = (int) Math.floor(q.v * r + 0.00000000001); + result = (int) (q.v * r + 0.00000000001); } else { - result = (int) Math.floor(q.u * (n - r) + 0.00000000001); + result = (int) (q.u * (n - r) + 0.00000000001); } if (result < minResult) { minResult = result;