You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/03/06 15:47:03 UTC
[commons-rng] 06/10: RNG-79: Modify benchmark to use uniform random
generator.
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 80c94a5916041fef587796abcafe646387c461c0
Author: aherbert <ah...@apache.org>
AuthorDate: Tue Mar 5 12:25:14 2019 +0000
RNG-79: Modify benchmark to use uniform random generator.
---
.../rng/examples/jmh/NextDoublePerformance.java | 102 +++++++++++----------
1 file changed, 56 insertions(+), 46 deletions(-)
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/NextDoublePerformance.java
index f182955..70620f3 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/NextDoublePerformance.java
@@ -41,112 +41,122 @@ import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@Fork(value = 1, jvmArgs = { "-server", "-Xms128M", "-Xmx128M" })
public class NextDoublePerformance {
- // Mimic the generation of the SplitMix64 algorithm
- // and a SplitMix32 algorithm to get a spread of input numbers.
-
- /**
- * The 64-bit golden ratio number.
- */
- private static final long GOLDEN_64 = 0x9e3779b97f4a7c15L;
- /**
- * The 32-bit golden ratio number.
- */
- private static final long GOLDEN_32 = 0x9e3779b9;
-
- /** The long state. */
- private long longState = ThreadLocalRandom.current().nextLong();
- /** The int state. */
- private int intState = ThreadLocalRandom.current().nextInt();
-
/**
- * Get the next long in the sequence.
+ * Mimic the generation of the SplitMix64 algorithm.
*
- * @return the long
- */
- private long nextLong() {
- return longState += GOLDEN_64;
- }
-
- /**
- * Get the next int in the sequence.
- *
- * @return the int
+ * <p>The final mixing step must be included otherwise the output numbers are sequential
+ * and the test may run with a lack of numbers with higher order bits.
*/
- private int nextInt() {
- return intState += GOLDEN_32;
+ @State(Scope.Benchmark)
+ public static class LongSource {
+ /** The state. */
+ private long state = ThreadLocalRandom.current().nextLong();
+
+ /**
+ * Get the next long.
+ *
+ * @return the long
+ */
+ public final long nextLong() {
+ long z = state += 0x9e3779b97f4a7c15L;
+ z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
+ z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+ return z ^ (z >>> 31);
+ }
+
+ /**
+ * Get the next int.
+ *
+ * <p>Returns the 32 high bits of Stafford variant 4 mix64 function as int.
+ *
+ * @return the int
+ */
+ public final int nextInt() {
+ long z = state += 0x9e3779b97f4a7c15L;
+ z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
+ return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
+ }
}
// Benchmark methods
/**
+ * @param source the source
* @return the long
*/
@Benchmark
- public long nextDoubleBaseline() {
- return nextLong();
+ public long nextDoubleBaseline(LongSource source) {
+ return source.nextLong();
}
/**
+ * @param source the source
* @return the double
*/
@Benchmark
- public double nextDoubleUsingBitsToDouble() {
+ public double nextDoubleUsingBitsToDouble(LongSource source) {
// Combine 11 bit unsigned exponent with value 1023 (768 + 255) with 52 bit mantissa
// 0x300L = 256 + 512 = 768
// 0x0ff = 255
// This makes a number in the range 1.0 to 2.0 so subtract 1.0
- return Double.longBitsToDouble(0x3ffL << 52 | nextLong() >>> 12) - 1.0;
+ return Double.longBitsToDouble(0x3ffL << 52 | source.nextLong() >>> 12) - 1.0;
}
/**
+ * @param source the source
* @return the double
*/
@Benchmark
- public double nextDoubleUsingMultiply52bits() {
- return (nextLong() >>> 12) * 0x1.0p-52d; // 1.0 / (1L << 52)
+ public double nextDoubleUsingMultiply52bits(LongSource source) {
+ return (source.nextLong() >>> 12) * 0x1.0p-52d; // 1.0 / (1L << 52)
}
/**
+ * @param source the source
* @return the double
*/
@Benchmark
- public double nextDoubleUsingMultiply53bits() {
- return (nextLong() >>> 11) * 0x1.0p-53d; // 1.0 / (1L << 53)
+ public double nextDoubleUsingMultiply53bits(LongSource source) {
+ return (source.nextLong() >>> 11) * 0x1.0p-53d; // 1.0 / (1L << 53)
}
/**
+ * @param source the source
* @return the int
*/
@Benchmark
- public int nextFloatBaseline() {
- return nextInt();
+ public int nextFloatBaseline(LongSource source) {
+ return source.nextInt();
}
/**
+ * @param source the source
* @return the float
*/
@Benchmark
- public float nextFloatUsingBitsToFloat() {
+ public float nextFloatUsingBitsToFloat(LongSource source) {
// Combine 8 bit unsigned exponent with value 127 (112 + 15) with 23 bit mantissa
// 0x70 = 64 + 32 + 16 = 112
// 0x0f = 15
// This makes a number in the range 1.0f to 2.0f so subtract 1.0f
- return Float.intBitsToFloat(0x7f << 23 | nextInt() >>> 9) - 1.0f;
+ return Float.intBitsToFloat(0x7f << 23 | source.nextInt() >>> 9) - 1.0f;
}
/**
+ * @param source the source
* @return the float
*/
@Benchmark
- public float nextFloatUsingMultiply23bits() {
- return (nextInt() >>> 9) * 0x1.0p-23f; // 1.0f / (1 << 23)
+ public float nextFloatUsingMultiply23bits(LongSource source) {
+ return (source.nextInt() >>> 9) * 0x1.0p-23f; // 1.0f / (1 << 23)
}
/**
+ * @param source the source
* @return the float
*/
@Benchmark
- public float nextFloatUsingMultiply24bits() {
- return (nextInt() >>> 8) * 0x1.0p-24f; // 1.0f / (1 << 24)
+ public float nextFloatUsingMultiply24bits(LongSource source) {
+ return (source.nextInt() >>> 8) * 0x1.0p-24f; // 1.0f / (1 << 24)
}
}