This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-rng.git
commit 92c6ac1f8dbd49f5e45a5717abcd911112a4c408 Author: aherbert <aherb...@apache.org> AuthorDate: Tue Apr 2 16:52:30 2019 +0100 RNG-88: Baseline the generation performance benchmark. The baseline is a minimal implementation that can be used to subtract the timing overhead of JMH from the results. Note: This renames the existing NextDoublePerformance to FloatingPointGenerationPerformance. This avoids confusion with the new baseline benchmarks. --- .../rng/examples/jmh/AbstractBenchmark.java | 48 ++++ .../jmh/BaselineGenerationPerformance.java | 237 +++++++++++++++++++ .../commons/rng/examples/jmh/BaselineSources.java | 97 ++++++++ .../commons/rng/examples/jmh/BaselineUtils.java | 259 +++++++++++++++++++++ ...ava => FloatingPointGenerationPerformance.java} | 2 +- .../jmh/NextBooleanGenerationPerformance.java | 72 ++++++ .../jmh/NextBytesGenerationPerformance.java | 74 ++++++ .../jmh/NextDoubleGenerationPerformance.java | 72 ++++++ .../jmh/NextFloatGenerationPerformance.java | 72 ++++++ .../examples/jmh/NextIntGenerationPerformance.java | 84 +++++++ .../jmh/NextLongGenerationPerformance.java | 84 +++++++ 11 files changed, 1100 insertions(+), 1 deletion(-) diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/AbstractBenchmark.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/AbstractBenchmark.java new file mode 100644 index 0000000..09d2b6d --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/AbstractBenchmark.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +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.Warmup; + +import java.util.concurrent.TimeUnit; + +/** + * Declares the JMH annotations for the benchmarks to compare the speed of generation of + * random numbers from the various source providers for {@link UniformRandomProvider}. + * + * <p>Note: Implementing this as an {@code @interface} annotation results in errors as the + * meta-annotation is not expanded by the JMH annotation processor. The processor does however + * allow all annotations to be inherited from abstract classes. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(value = 1, jvmArgs = { "-server", "-Xms128M", "-Xmx128M" }) +@State(Scope.Benchmark) +public abstract class AbstractBenchmark { + // Empty. Serves as an annotation placeholder. +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineGenerationPerformance.java new file mode 100644 index 0000000..1a94885 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineGenerationPerformance.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +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.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +/** + * Benchmarks to check linearity in the baseline implementations of {@link UniformRandomProvider}. + * + * <p>These ordinarily do not need to be run. The benchmarks can be used to determine + * if the baseline scales linearly with workload. If not then the JVM has removed the + * baseline from the testing loop given that its result is predictable. The ideal + * baseline will:</p> + * + * <ul> + * <li>Run as fast as possible + * <li>Not be removed from the execution path + * </ul> + * + * <p>The results of this benchmark should be plotted for each method using [numValues] vs [run time] + * to check linearity.</p> + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) +@State(Scope.Benchmark) +@Fork(value = 1, jvmArgs = { "-server", "-Xms128M", "-Xmx128M" }) +public class BaselineGenerationPerformance { + /** + * The size of the array for testing {@link UniformRandomProvider#nextBytes(byte[])}. + * + * <p>This is a small prime number (127). This satisfies the following requirements:</p> + * + * <ul> + * <li>The number of bytes will be allocated when testing so the allocation overhead + * should be small. + * <li>The number must be set so that filling the bytes from an {@code int} or {@code long} + * source has no advantage for the 32-bit source, e.g. the same number of underlying bits have + * to be generated. Note: 127 / 4 ~ 32 ints or 127 / 8 ~ 16 longs. + * <li>The number should not be a factor of 4 to prevent filling completely using a 32-bit + * source. This tests the edge case of partial fill. + * </ul> + */ + static final int NEXT_BYTES_SIZE = 127; + + /** + * The upper limit for testing {@link UniformRandomProvider#nextInt(int)}. + * + * <p>This is the biggest prime number for an {@code int} (2147483629) to give a worst case + * run-time for the method.</p> + */ + static final int NEXT_INT_LIMIT = 2147483629; + + /** + * The upper limit for testing {@link UniformRandomProvider#nextLong(long)}. + * + * <p>This is the biggest prime number for a {@code long} (9223372036854775783L) to + * give a worst case run-time for the method.</p> + */ + static final long NEXT_LONG_LIMIT = 9223372036854775783L; + + /** + * The provider for testing {@link UniformRandomProvider#nextByte()} and + * {@link UniformRandomProvider#nextByte(int)}. + */ + private UniformRandomProvider nextBytesProvider = BaselineUtils.getNextBytes(); + + /** + * The provider for testing {@link UniformRandomProvider#nextInt()} and + * {@link UniformRandomProvider#nextInt(int)}. + */ + private UniformRandomProvider nextIntProvider = BaselineUtils.getNextInt(); + + /** + * The provider for testing {@link UniformRandomProvider#nextLong()} and + * {@link UniformRandomProvider#nextLong(long)}. + */ + private UniformRandomProvider nextLongProvider = BaselineUtils.getNextLong(); + + /** + * The provider for testing {@link UniformRandomProvider#nextBoolean()}. + */ + private UniformRandomProvider nextBooleanProvider = BaselineUtils.getNextBoolean(); + + /** + * The provider for testing {@link UniformRandomProvider#nextFloat()}. + */ + private UniformRandomProvider nextFloatProvider = BaselineUtils.getNextFloat(); + + /** + * The provider for testing {@link UniformRandomProvider#nextDouble()}. + */ + private UniformRandomProvider nextDoubleProvider = BaselineUtils.getNextDouble(); + + /** + * Number of random values to generate when testing linearity. This must be high to avoid + * JIT optimisation of small loop constructs. + * + * <p>Note: Following the convention in the JMH Blackhole::consumCPU(long) method + * the loops are constructed to count down (although since there is no consumption + * of the loop counter the loop construct may be rewritten anyway). + */ + @Param({"50000", "100000", "150000", "200000", "250000"}) + private int numValues; + + /** + * Exercise the {@link UniformRandomProvider#nextBytes(byte[])} method. + * + * <p>Note: Currently there is not a test for + * {@link UniformRandomProvider#nextBytes(byte[], int, int)} since the two methods are + * implemented by the base Int/LongProvider class using the same code. + * + * @param bh Data sink. + */ + @Benchmark + public void nextBytes(Blackhole bh) { + // The array allocation is not part of the benchmark. + final byte[] result = new byte[NEXT_BYTES_SIZE]; + for (int i = numValues; i > 0; i--) { + nextBytesProvider.nextBytes(result); + bh.consume(result); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextInt()} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextInt(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextIntProvider.nextInt()); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextInt(int)} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextIntN(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextIntProvider.nextInt(NEXT_INT_LIMIT)); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextLong()} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextLong(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextLongProvider.nextLong()); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextLong(long)} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextLongN(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextLongProvider.nextLong(NEXT_LONG_LIMIT)); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextBoolean()} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextBoolean(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextBooleanProvider.nextBoolean()); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextFloat()} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextFloat(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextFloatProvider.nextFloat()); + } + } + + /** + * Exercise the {@link UniformRandomProvider#nextDouble()} method. + * + * @param bh Data sink. + */ + @Benchmark + public void nextDouble(Blackhole bh) { + for (int i = numValues; i > 0; i--) { + bh.consume(nextDoubleProvider.nextDouble()); + } + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineSources.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineSources.java new file mode 100644 index 0000000..d5d55ad --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineSources.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +/** + * Defines the benchmark state to retrieve the various "RandomSource"s. + * + * <p>A baseline implementation for the {@link UniformRandomProvider} must be provided by + * implementing classes. + */ +@State(Scope.Benchmark) +public abstract class BaselineSources { + /** The keyword identifying the baseline implementation. */ + private static final String BASELINE = "BASELINE"; + + /** + * RNG providers. + * + * <p>List all providers that do not require additional constructor arguments. This list + * is in the declared order of {@link RandomSource}.</p> + */ + @Param({BASELINE, + "JDK", + "WELL_512_A", + "WELL_1024_A", + "WELL_19937_A", + "WELL_19937_C", + "WELL_44497_A", + "WELL_44497_B", + "MT", + "ISAAC", + "SPLIT_MIX_64", + "XOR_SHIFT_1024_S", + "TWO_CMRES", + "MT_64", + "MWC_256", + "KISS", + "XOR_SHIFT_1024_S_PHI", + }) + private String randomSourceName; + + /** RNG. */ + private UniformRandomProvider provider; + + /** + * Gets the generator. + * + * @return the RNG. + */ + public UniformRandomProvider getGenerator() { + return provider; + } + + /** Instantiates generator. This need only be done once per set of iterations. */ + @Setup(value = Level.Trial) + public void setup() { + if (BASELINE.equals(randomSourceName)) { + provider = createBaseline(); + } else { + final RandomSource randomSource = RandomSource.valueOf(randomSourceName); + provider = RandomSource.create(randomSource); + } + } + + /** + * Creates the baseline {@link UniformRandomProvider}. + * + * <p>This should implement the method(s) that will be tested. The speed of this RNG is expected + * to create a baseline against which all other generators will be compared.</p> + * + * @return the baseline RNG. + */ + protected abstract UniformRandomProvider createBaseline(); +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineUtils.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineUtils.java new file mode 100644 index 0000000..a882f2c --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/BaselineUtils.java @@ -0,0 +1,259 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; + +/** + * Defines baseline implementations for the {@link UniformRandomProvider}. + */ +public final class BaselineUtils { + /** No public construction. */ + private BaselineUtils() {} + + /** + * Default implementation of {@link UniformRandomProvider} that does nothing. + * + * <p>Note: This is not a good baseline as the JVM can optimise the predictable result + * of the method calls. This is here for convenience when implementing + * UniformRandomProvider. + */ + private abstract static class DefaultProvider implements UniformRandomProvider { + @Override + public void nextBytes(byte[] bytes) {} + + @Override + public void nextBytes(byte[] bytes, int start, int len) {} + + @Override + public int nextInt() { return 0; } + + @Override + public int nextInt(int n) { return 0; } + + @Override + public long nextLong() { return 0; } + + @Override + public long nextLong(long n) { return 0; } + + @Override + public boolean nextBoolean() { return false; } + + @Override + public float nextFloat() { return 0; } + + @Override + public double nextDouble() { return 0; } + } + + // The baseline implementation of nextBytes has 2 options: + // + // 1. Copy the same value into each positions. + // 2. Increment a counter and copy into each position. + // + // Option 1 provides the opportunity for the JVM to inline the copy through the array. + // Option 2 introduces a counter overhead. + + /** + * Baseline implementation for {@link UniformRandomProvider#nextBytes(byte[])} and + * {@link UniformRandomProvider#nextBytes(byte[], int, int)}. + */ + private static final class BaselineNextBytes extends DefaultProvider { + /** + * The fixed value to fill the byte array. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private byte value; + + @Override + public void nextBytes(byte[] bytes) { + for (int i = 0; i < bytes.length; i++) { + bytes[i] = value; + } + } + + @Override + public void nextBytes(byte[] bytes, int start, int len) { + for (int i = start; i < len; i++) { + bytes[i] = value; + } + } + } + + /** + * Baseline implementation for {@link UniformRandomProvider#nextInt()} and + * {@link UniformRandomProvider#nextInt(int)}. + */ + private static final class BaselineNextInt extends DefaultProvider { + /** + * The fixed value to return. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private int value; + + @Override + public int nextInt() { + return value; + } + + @Override + public int nextInt(int n) { + return value; + } + } + + /** + * Baseline implementation for {@link UniformRandomProvider#nextLong()} and + * {@link UniformRandomProvider#nextLong(long)}. + */ + private static final class BaselineNextLong extends DefaultProvider { + /** + * The fixed value to return. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private long value; + + @Override + public long nextLong() { + return value; + } + + @Override + public long nextLong(long n) { + return value; + } + } + + /** + * Baseline implementation for {@link UniformRandomProvider#nextBoolean()}. + */ + private static final class BaselineNextBoolean extends DefaultProvider { + /** + * The fixed value to return. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private boolean value; + + @Override + public boolean nextBoolean() { + return value; + } + } + + /** + * Baseline implementation for {@link UniformRandomProvider#nextFloat()}. + */ + private static final class BaselineNextFloat extends DefaultProvider { + /** + * The fixed value to return. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private float value; + + @Override + public float nextFloat() { + return value; + } + } + + /** + * Baseline implementation for {@link UniformRandomProvider#nextDouble()}. + */ + private static final class BaselineNextDouble extends DefaultProvider { + /** + * The fixed value to return. + * + * <p><strong>DON'T</strong> make this final! + * This must be a viewed by the JVM as something that cannot be optimised away. + */ + private double value; + + @Override + public double nextDouble() { + return value; + } + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextBytes(byte[])} and + * {@link UniformRandomProvider#nextBytes(byte[], int, int)}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextBytes() { + return new BaselineNextBytes(); + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextInt()} and + * {@link UniformRandomProvider#nextInt(int)}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextInt() { + return new BaselineNextInt(); + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextLong()} and + * {@link UniformRandomProvider#nextLong(long)}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextLong() { + return new BaselineNextLong(); + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextBoolean()}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextBoolean() { + return new BaselineNextBoolean(); + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextFloat()}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextFloat() { + return new BaselineNextFloat(); + } + + /** + * Gets a baseline provider for {@link UniformRandomProvider#nextDouble()}. + * + * @return The baseline provider. + */ + public static UniformRandomProvider getNextDouble() { + return new BaselineNextDouble(); + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoublePerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/FloatingPointGenerationPerformance.java similarity index 99% rename from commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoublePerformance.java rename to commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/FloatingPointGenerationPerformance.java index 70620f3..5125032 100644 --- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoublePerformance.java +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/FloatingPointGenerationPerformance.java @@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit; @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @State(Scope.Benchmark) @Fork(value = 1, jvmArgs = { "-server", "-Xms128M", "-Xmx128M" }) -public class NextDoublePerformance { +public class FloatingPointGenerationPerformance { /** * Mimic the generation of the SplitMix64 algorithm. * diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBooleanGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBooleanGenerationPerformance.java new file mode 100644 index 0000000..4af04e7 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBooleanGenerationPerformance.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextBoolean()}. + */ +public class NextBooleanGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextBoolean(); + } + } + + /** The value. */ + private boolean value; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning a {@code boolean}. + * + * @return the value + */ + @Benchmark + public boolean baselineBoolean() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextBoolean()} method. + * + * @param sources Source of randomness. + * @return the boolean + */ + @Benchmark + public boolean nextBoolean(Sources sources) { + return sources.getGenerator().nextBoolean(); + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBytesGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBytesGenerationPerformance.java new file mode 100644 index 0000000..ba44416 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextBytesGenerationPerformance.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextBytes(byte[])}. + */ +public class NextBytesGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextBytes(); + } + } + + /** The value. This is a pre-allocated array. */ + private byte[] value = new byte[BaselineGenerationPerformance.NEXT_BYTES_SIZE]; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning a {@code byte[]}. + * + * @return the value + */ + @Benchmark + public byte[] baselineBytes() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextBytes(byte[])} method. + * + * @param sources Source of randomness. + * @return the boolean + */ + @Benchmark + public byte[] nextBytes(Sources sources) { + // The array allocation is not part of the benchmark. + sources.getGenerator().nextBytes(value); + return value; + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoubleGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoubleGenerationPerformance.java new file mode 100644 index 0000000..0919e59 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextDoubleGenerationPerformance.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextDouble()}. + */ +public class NextDoubleGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextDouble(); + } + } + + /** The value. */ + private double value; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning a {@code double}. + * + * @return the value + */ + @Benchmark + public double baselineDouble() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextDouble()} method. + * + * @param sources Source of randomness. + * @return the double + */ + @Benchmark + public double nextDouble(Sources sources) { + return sources.getGenerator().nextDouble(); + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextFloatGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextFloatGenerationPerformance.java new file mode 100644 index 0000000..ec63bed --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextFloatGenerationPerformance.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextFloat()}. + */ +public class NextFloatGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextFloat(); + } + } + + /** The value. */ + private float value; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning a {@code float}. + * + * @return the value + */ + @Benchmark + public float baselineFloat() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextFloat()} method. + * + * @param sources Source of randomness. + * @return the float + */ + @Benchmark + public float nextFloat(Sources sources) { + return sources.getGenerator().nextFloat(); + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextIntGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextIntGenerationPerformance.java new file mode 100644 index 0000000..f10e949 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextIntGenerationPerformance.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextInt()} and + * {@link UniformRandomProvider#nextInt(int)}. + */ +public class NextIntGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextInt(); + } + } + + /** The value. */ + private int value; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning an {@code int}. + * + * @return the value + */ + @Benchmark + public int baselineInt() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextInt()} method. + * + * @param sources Source of randomness. + * @return the int + */ + @Benchmark + public int nextInt(Sources sources) { + return sources.getGenerator().nextInt(); + } + + /** + * Exercise the {@link UniformRandomProvider#nextInt(int)} method. + * + * @param sources Source of randomness. + * @return the int + */ + @Benchmark + public int nextIntN(Sources sources) { + return sources.getGenerator().nextInt(BaselineGenerationPerformance.NEXT_INT_LIMIT); + } +} diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextLongGenerationPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextLongGenerationPerformance.java new file mode 100644 index 0000000..2a71f80 --- /dev/null +++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/NextLongGenerationPerformance.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.rng.examples.jmh; + +import org.apache.commons.rng.UniformRandomProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +/** + * Executes benchmark to compare the speed of generation of random numbers from the + * various source providers for {@link UniformRandomProvider#nextLong()} and + * {@link UniformRandomProvider#nextLong(long)}. + */ +public class NextLongGenerationPerformance extends AbstractBenchmark { + /** + * The benchmark state (retrieve the various "RandomSource"s). + */ + @State(Scope.Benchmark) + public static class Sources extends BaselineSources { + @Override + protected UniformRandomProvider createBaseline() { + return BaselineUtils.getNextLong(); + } + } + + /** The value. */ + private long value; + + /** + * Baseline for a JMH method call with no return value. + */ + @Benchmark + public void baselineVoid() { + // Do nothing, this is a baseline + } + + /** + * Baseline for a JMH method call returning a {@code long}. + * + * @return the value + */ + @Benchmark + public long baselineLong() { + return value; + } + + /** + * Exercise the {@link UniformRandomProvider#nextLong()} method. + * + * @param sources Source of randomness. + * @return the long + */ + @Benchmark + public long nextLong(Sources sources) { + return sources.getGenerator().nextLong(); + } + + /** + * Exercise the {@link UniformRandomProvider#nextLong(long)} method. + * + * @param sources Source of randomness. + * @return the long + */ + @Benchmark + public long nextLongN(Sources sources) { + return sources.getGenerator().nextLong(BaselineGenerationPerformance.NEXT_LONG_LIMIT); + } +}