| /* |
| * 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.simple; |
| |
| import org.openjdk.jmh.annotations.Benchmark; |
| import org.openjdk.jmh.annotations.BenchmarkMode; |
| import org.openjdk.jmh.annotations.Fork; |
| import org.openjdk.jmh.annotations.Level; |
| 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.Setup; |
| import org.openjdk.jmh.annotations.State; |
| import org.openjdk.jmh.annotations.Warmup; |
| import org.openjdk.jmh.infra.Blackhole; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Arrays; |
| import java.util.concurrent.TimeUnit; |
| |
| import org.apache.commons.rng.UniformRandomProvider; |
| import org.apache.commons.rng.core.source32.ISAACRandom; |
| import org.apache.commons.rng.core.source32.JDKRandom; |
| import org.apache.commons.rng.core.source32.KISSRandom; |
| import org.apache.commons.rng.core.source32.MersenneTwister; |
| import org.apache.commons.rng.core.source32.MultiplyWithCarry256; |
| import org.apache.commons.rng.core.source32.Well1024a; |
| import org.apache.commons.rng.core.source32.Well19937a; |
| import org.apache.commons.rng.core.source32.Well19937c; |
| import org.apache.commons.rng.core.source32.Well44497a; |
| import org.apache.commons.rng.core.source32.Well44497b; |
| import org.apache.commons.rng.core.source32.Well512a; |
| import org.apache.commons.rng.core.source32.XoRoShiRo64Star; |
| import org.apache.commons.rng.core.source32.XoRoShiRo64StarStar; |
| import org.apache.commons.rng.core.source32.XoShiRo128Plus; |
| import org.apache.commons.rng.core.source32.XoShiRo128StarStar; |
| import org.apache.commons.rng.core.source64.MersenneTwister64; |
| import org.apache.commons.rng.core.source64.SplitMix64; |
| import org.apache.commons.rng.core.source64.TwoCmres; |
| import org.apache.commons.rng.core.source64.XoRoShiRo128Plus; |
| import org.apache.commons.rng.core.source64.XoRoShiRo128StarStar; |
| import org.apache.commons.rng.core.source64.XoShiRo256Plus; |
| import org.apache.commons.rng.core.source64.XoShiRo256StarStar; |
| import org.apache.commons.rng.core.source64.XoShiRo512Plus; |
| import org.apache.commons.rng.core.source64.XoShiRo512StarStar; |
| import org.apache.commons.rng.core.source64.XorShift1024Star; |
| import org.apache.commons.rng.core.source64.XorShift1024StarPhi; |
| import org.apache.commons.rng.core.util.NumberFactory; |
| import org.apache.commons.rng.examples.jmh.RandomSourceValues; |
| import org.apache.commons.rng.simple.RandomSource; |
| import org.apache.commons.rng.simple.internal.ProviderBuilder.RandomSourceInternal; |
| import org.apache.commons.rng.simple.internal.SeedFactory; |
| |
| /** |
| * Executes a benchmark to compare the speed of construction of random number providers. |
| * |
| * <p>Note that random number providers are created and then used. Thus the construction time must |
| * be analysed together with the run time performance benchmark (see for example |
| * {@link org.apache.commons.rng.examples.jmh.core.NextLongGenerationPerformance |
| * NextIntGenerationPerformance} and |
| * {@link org.apache.commons.rng.examples.jmh.core.NextLongGenerationPerformance |
| * NextLongGenerationPerformance}). |
| * |
| * <pre> |
| * [Total time] = [Construction time] + [Run time] |
| * </pre> |
| * |
| * <p>Selection of a suitable random number provider based on construction speed should consider |
| * when the construction time is a large fraction of the run time. In the majority of cases the |
| * run time will be the largest component of the total time and the provider should be selected |
| * based on its other properties such as the period, statistical randomness and speed. |
| */ |
| @BenchmarkMode(Mode.AverageTime) |
| @OutputTimeUnit(TimeUnit.MICROSECONDS) |
| @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) |
| @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) |
| @State(Scope.Benchmark) |
| @Fork(value = 1, jvmArgs = { "-server", "-Xms512M", "-Xmx512M" }) |
| public class ConstructionPerformance { |
| |
| /** The number of different constructor seeds. */ |
| private static final int SEEDS = 500; |
| /** |
| * The maximum seed array size. This is irrespective of data type just to ensure |
| * there is enough data in the random seeds. The value is for WELL_44497_A. |
| */ |
| private static final int MAX_SEED_SIZE = 1391; |
| /** The {@link Long} seeds. */ |
| private static final Long[] LONG_SEEDS; |
| /** The {@link Integer} seeds. */ |
| private static final Integer[] INTEGER_SEEDS; |
| /** The {@code long[]} seeds. */ |
| private static final long[][] LONG_ARRAY_SEEDS; |
| /** The {@code int[]} seeds. */ |
| private static final int[][] INT_ARRAY_SEEDS; |
| /** The {@code byte[]} seeds. */ |
| private static final byte[][] BYTE_ARRAY_SEEDS; |
| |
| /** |
| * The values. Must NOT be final to prevent JVM optimisation! |
| * This is used to test the speed of the BlackHole consuming an object. |
| */ |
| private Object[] values; |
| |
| static { |
| LONG_SEEDS = new Long[SEEDS]; |
| INTEGER_SEEDS = new Integer[SEEDS]; |
| LONG_ARRAY_SEEDS = new long[SEEDS][]; |
| INT_ARRAY_SEEDS = new int[SEEDS][]; |
| BYTE_ARRAY_SEEDS = new byte[SEEDS][]; |
| final UniformRandomProvider rng = RandomSource.create(RandomSource.XOR_SHIFT_1024_S_PHI); |
| for (int i = 0; i < SEEDS; i++) { |
| final long[] longArray = new long[MAX_SEED_SIZE]; |
| final int[] intArray = new int[MAX_SEED_SIZE]; |
| for (int j = 0; j < MAX_SEED_SIZE; j++) { |
| longArray[j] = rng.nextLong(); |
| intArray[j] = (int) longArray[j]; |
| } |
| LONG_SEEDS[i] = longArray[0]; |
| INTEGER_SEEDS[i] = intArray[0]; |
| LONG_ARRAY_SEEDS[i] = longArray; |
| INT_ARRAY_SEEDS[i] = intArray; |
| BYTE_ARRAY_SEEDS[i] = NumberFactory.makeByteArray(longArray); |
| } |
| } |
| |
| /** |
| * Default constructor to initialize state. |
| */ |
| public ConstructionPerformance() { |
| values = new Object[SEEDS]; |
| for (int i = 0; i < SEEDS; i++) { |
| values[i] = new Object(); |
| } |
| } |
| |
| /** |
| * The benchmark state (retrieve the various "RandomSource"s). |
| */ |
| @State(Scope.Benchmark) |
| public static class Sources extends RandomSourceValues { |
| /** The native seeds. */ |
| private Object[] nativeSeeds; |
| |
| /** The native seeds with arrays truncated to 1 element. */ |
| private Object[] nativeSeeds1; |
| |
| /** The {@code byte[]} seeds, truncated to the appropriate length for the native seed type. */ |
| private byte[][] byteSeeds; |
| |
| /** The implementing class for the random source. */ |
| private Class<?> implementingClass; |
| |
| /** The constructor. */ |
| private Constructor<Object> constructor; |
| |
| /** |
| * Gets the native seeds for the RandomSource. |
| * |
| * @return the native seeds |
| */ |
| public Object[] getNativeSeeds() { |
| return nativeSeeds; |
| } |
| |
| /** |
| * Gets the native seeds for the RandomSource with arrays truncated to length 1. |
| * |
| * @return the native seeds |
| */ |
| public Object[] getNativeSeeds1() { |
| return nativeSeeds1; |
| } |
| |
| /** |
| * Gets the native seeds for the RandomSource. |
| * |
| * @return the native seeds |
| */ |
| public byte[][] getByteSeeds() { |
| return byteSeeds; |
| } |
| |
| /** |
| * Gets the implementing class. |
| * |
| * @return the implementing class |
| */ |
| public Class<?> getImplementingClass() { |
| return implementingClass; |
| } |
| |
| /** |
| * Gets the constructor. |
| * |
| * @return the constructor |
| */ |
| public Constructor<Object> getConstructor() { |
| return constructor; |
| } |
| |
| /** |
| * Create the random source and the test seeds. |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| @Setup(Level.Trial) |
| public void setup() { |
| super.setup(); |
| final RandomSource randomSource = getRandomSource(); |
| nativeSeeds = findNativeSeeds(randomSource); |
| |
| // Truncate array seeds to length 1 |
| if (nativeSeeds[0].getClass().isArray()) { |
| nativeSeeds1 = new Object[SEEDS]; |
| for (int i = 0; i < SEEDS; i++) { |
| nativeSeeds1[i] = copy(nativeSeeds[i], 1); |
| } |
| } else { |
| // N/A |
| nativeSeeds1 = nativeSeeds; |
| } |
| |
| // Convert seeds to bytes |
| byteSeeds = new byte[SEEDS][]; |
| final int byteSize = findNativeSeedLength(randomSource) * |
| findNativeSeedElementByteSize(randomSource); |
| for (int i = 0; i < SEEDS; i++) { |
| byteSeeds[i] = Arrays.copyOf(BYTE_ARRAY_SEEDS[i], byteSize); |
| } |
| |
| // Cache the class type and constructor |
| implementingClass = getRandomSourceInternal(randomSource).getRng(); |
| try { |
| constructor = (Constructor<Object>) implementingClass.getConstructor(nativeSeeds[0].getClass()); |
| } catch (NoSuchMethodException ex) { |
| throw new IllegalStateException("Failed to find the constructor", ex); |
| } |
| } |
| |
| /** |
| * Copy the specified length of the provided array object. |
| * |
| * @param object the object |
| * @param length the length |
| * @return the copy |
| */ |
| private static Object copy(Object object, int length) { |
| if (object instanceof int[]) { |
| return Arrays.copyOf((int[]) object, length); |
| } |
| if (object instanceof long[]) { |
| return Arrays.copyOf((long[]) object, length); |
| } |
| throw new AssertionError("Unknown seed array"); |
| } |
| |
| /** |
| * Find the native seeds for the RandomSource. |
| * |
| * @param randomSource the random source |
| * @return the native seeds |
| */ |
| private static Object[] findNativeSeeds(RandomSource randomSource) { |
| switch (randomSource) { |
| case TWO_CMRES: |
| case TWO_CMRES_SELECT: |
| return INTEGER_SEEDS; |
| case JDK: |
| case SPLIT_MIX_64: |
| return LONG_SEEDS; |
| case WELL_512_A: |
| case WELL_1024_A: |
| case WELL_19937_A: |
| case WELL_19937_C: |
| case WELL_44497_A: |
| case WELL_44497_B: |
| case MT: |
| case ISAAC: |
| case MWC_256: |
| case KISS: |
| case XO_RO_SHI_RO_64_S: |
| case XO_RO_SHI_RO_64_SS: |
| case XO_SHI_RO_128_PLUS: |
| case XO_SHI_RO_128_SS: |
| return INT_ARRAY_SEEDS; |
| case XOR_SHIFT_1024_S: |
| case XOR_SHIFT_1024_S_PHI: |
| case MT_64: |
| case XO_RO_SHI_RO_128_PLUS: |
| case XO_RO_SHI_RO_128_SS: |
| case XO_SHI_RO_256_PLUS: |
| case XO_SHI_RO_256_SS: |
| case XO_SHI_RO_512_PLUS: |
| case XO_SHI_RO_512_SS: |
| return LONG_ARRAY_SEEDS; |
| default: |
| throw new AssertionError("Unknown native seed"); |
| } |
| } |
| |
| /** |
| * Find the length of the native seed (number of elements). |
| * |
| * @param randomSource the random source |
| * @return the seed length |
| */ |
| private static int findNativeSeedLength(RandomSource randomSource) { |
| switch (randomSource) { |
| case JDK: |
| case SPLIT_MIX_64: |
| case TWO_CMRES: |
| case TWO_CMRES_SELECT: |
| return 1; |
| case WELL_512_A: |
| return 16; |
| case WELL_1024_A: |
| return 32; |
| case WELL_19937_A: |
| case WELL_19937_C: |
| return 624; |
| case WELL_44497_A: |
| case WELL_44497_B: |
| return 1391; |
| case MT: |
| return 624; |
| case ISAAC: |
| return 256; |
| case XOR_SHIFT_1024_S: |
| case XOR_SHIFT_1024_S_PHI: |
| return 16; |
| case MT_64: |
| return 312; |
| case MWC_256: |
| return 257; |
| case KISS: |
| return 4; |
| case XO_RO_SHI_RO_64_S: |
| case XO_RO_SHI_RO_64_SS: |
| return 2; |
| case XO_SHI_RO_128_PLUS: |
| case XO_SHI_RO_128_SS: |
| return 4; |
| case XO_RO_SHI_RO_128_PLUS: |
| case XO_RO_SHI_RO_128_SS: |
| return 2; |
| case XO_SHI_RO_256_PLUS: |
| case XO_SHI_RO_256_SS: |
| return 4; |
| case XO_SHI_RO_512_PLUS: |
| case XO_SHI_RO_512_SS: |
| return 8; |
| default: |
| throw new AssertionError("Unknown native seed size"); |
| } |
| } |
| |
| /** |
| * Find the byte size of a single element of the native seed. |
| * |
| * @param randomSource the random source |
| * @return the seed element byte size |
| */ |
| private static int findNativeSeedElementByteSize(RandomSource randomSource) { |
| switch (randomSource) { |
| case JDK: |
| case WELL_512_A: |
| case WELL_1024_A: |
| case WELL_19937_A: |
| case WELL_19937_C: |
| case WELL_44497_A: |
| case WELL_44497_B: |
| case MT: |
| case ISAAC: |
| case TWO_CMRES: |
| case TWO_CMRES_SELECT: |
| case MWC_256: |
| case KISS: |
| case XO_RO_SHI_RO_64_S: |
| case XO_RO_SHI_RO_64_SS: |
| case XO_SHI_RO_128_PLUS: |
| case XO_SHI_RO_128_SS: |
| return 4; // int |
| case SPLIT_MIX_64: |
| case XOR_SHIFT_1024_S: |
| case XOR_SHIFT_1024_S_PHI: |
| case MT_64: |
| case XO_RO_SHI_RO_128_PLUS: |
| case XO_RO_SHI_RO_128_SS: |
| case XO_SHI_RO_256_PLUS: |
| case XO_SHI_RO_256_SS: |
| case XO_SHI_RO_512_PLUS: |
| case XO_SHI_RO_512_SS: |
| return 8; // long |
| default: |
| throw new AssertionError("Unknown native seed element byte size"); |
| } |
| } |
| |
| /** |
| * Gets the random source internal. |
| * |
| * @param randomSource the random source |
| * @return the random source internal |
| */ |
| private static RandomSourceInternal getRandomSourceInternal(RandomSource randomSource) { |
| switch (randomSource) { |
| case JDK: return RandomSourceInternal.JDK; |
| case WELL_512_A: return RandomSourceInternal.WELL_512_A; |
| case WELL_1024_A: return RandomSourceInternal.WELL_1024_A; |
| case WELL_19937_A: return RandomSourceInternal.WELL_19937_A; |
| case WELL_19937_C: return RandomSourceInternal.WELL_19937_C; |
| case WELL_44497_A: return RandomSourceInternal.WELL_44497_A; |
| case WELL_44497_B: return RandomSourceInternal.WELL_44497_B; |
| case MT: return RandomSourceInternal.MT; |
| case ISAAC: return RandomSourceInternal.ISAAC; |
| case TWO_CMRES: return RandomSourceInternal.TWO_CMRES; |
| case TWO_CMRES_SELECT: return RandomSourceInternal.TWO_CMRES_SELECT; |
| case MWC_256: return RandomSourceInternal.MWC_256; |
| case KISS: return RandomSourceInternal.KISS; |
| case SPLIT_MIX_64: return RandomSourceInternal.SPLIT_MIX_64; |
| case XOR_SHIFT_1024_S: return RandomSourceInternal.XOR_SHIFT_1024_S; |
| case MT_64: return RandomSourceInternal.MT_64; |
| case XOR_SHIFT_1024_S_PHI: return RandomSourceInternal.XOR_SHIFT_1024_S_PHI; |
| case XO_RO_SHI_RO_64_S: return RandomSourceInternal.XO_RO_SHI_RO_64_S; |
| case XO_RO_SHI_RO_64_SS: return RandomSourceInternal.XO_RO_SHI_RO_64_SS; |
| case XO_SHI_RO_128_PLUS: return RandomSourceInternal.XO_SHI_RO_128_PLUS; |
| case XO_SHI_RO_128_SS: return RandomSourceInternal.XO_SHI_RO_128_SS; |
| case XO_RO_SHI_RO_128_PLUS: return RandomSourceInternal.XO_RO_SHI_RO_128_PLUS; |
| case XO_RO_SHI_RO_128_SS: return RandomSourceInternal.XO_RO_SHI_RO_128_SS; |
| case XO_SHI_RO_256_PLUS: return RandomSourceInternal.XO_SHI_RO_256_PLUS; |
| case XO_SHI_RO_256_SS: return RandomSourceInternal.XO_SHI_RO_256_SS; |
| case XO_SHI_RO_512_PLUS: return RandomSourceInternal.XO_SHI_RO_512_PLUS; |
| case XO_SHI_RO_512_SS: return RandomSourceInternal.XO_SHI_RO_512_SS; |
| default: |
| throw new AssertionError("Unknown random source internal"); |
| } |
| } |
| } |
| |
| /** |
| * The number of {@code int} values that are required to seed a generator. |
| */ |
| @State(Scope.Benchmark) |
| public static class IntSizes { |
| /** The number of values. */ |
| @Param({"2", |
| "4", |
| "32", |
| "128", // Legacy limit on array size generation |
| "256", |
| "257", |
| "624", |
| "1391", |
| }) |
| private int size; |
| |
| /** |
| * Gets the number of {@code int} values required. |
| * |
| * @return the size |
| */ |
| public int getSize() { |
| return size; |
| } |
| } |
| |
| /** |
| * The number of {@code long} values that are required to seed a generator. |
| */ |
| @State(Scope.Benchmark) |
| public static class LongSizes { |
| /** The number of values. */ |
| @Param({"2", |
| "4", |
| "8", |
| "16", |
| "128", // Legacy limit on array size generation |
| "312", |
| }) |
| private int size; |
| |
| /** |
| * Gets the number of {@code long} values required. |
| * |
| * @return the size |
| */ |
| public int getSize() { |
| return size; |
| } |
| } |
| |
| /** |
| * Baseline for JMH consuming a number of constructed objects. |
| * This shows the JMH timing overhead for all the construction benchmarks. |
| * |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void baselineConsumeObject(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(values[i]); |
| } |
| } |
| |
| /** |
| * Baseline for JMH consuming a number of new objects. |
| * |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newObject(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Object()); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newJDKRandom(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new JDKRandom(LONG_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell512a(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well512a(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell1024a(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well1024a(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell19937a(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well19937a(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell19937c(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well19937c(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell44497a(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well44497a(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newWell44497b(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new Well44497b(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newMersenneTwister(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new MersenneTwister(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newISAACRandom(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new ISAACRandom(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newSplitMix64(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new SplitMix64(LONG_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXorShift1024Star(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XorShift1024Star(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newTwoCmres(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new TwoCmres(INTEGER_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newMersenneTwister64(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new MersenneTwister64(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newMultiplyWithCarry256(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new MultiplyWithCarry256(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newKISSRandom(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new KISSRandom(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXorShift1024StarPhi(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XorShift1024StarPhi(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoRoShiRo64Star(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoRoShiRo64Star(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoRoShiRo64StarStar(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoRoShiRo64StarStar(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo128Plus(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo128Plus(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo128StarStar(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo128StarStar(INT_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoRoShiRo128Plus(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoRoShiRo128Plus(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoRoShiRo128StarStar(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoRoShiRo128StarStar(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo256Plus(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo256Plus(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo256StarStar(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo256StarStar(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo512Plus(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo512Plus(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void newXoShiRo512StarStar(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(new XoShiRo512StarStar(LONG_ARRAY_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * Create a new instance using reflection with a cached constructor. |
| * |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| * @throws InvocationTargetException If reflection failed. |
| * @throws IllegalAccessException If reflection failed. |
| * @throws InstantiationException If reflection failed. |
| */ |
| @Benchmark |
| public void newInstance(Sources sources, Blackhole bh) throws InstantiationException, |
| IllegalAccessException, InvocationTargetException { |
| final Object[] nativeSeeds = sources.getNativeSeeds(); |
| final Constructor<?> constructor = sources.getConstructor(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(constructor.newInstance(nativeSeeds[i])); |
| } |
| } |
| |
| /** |
| * Create a new instance using reflection to lookup the constructor then invoke it. |
| * |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| * @throws InvocationTargetException If reflection failed. |
| * @throws IllegalAccessException If reflection failed. |
| * @throws InstantiationException If reflection failed. |
| * @throws SecurityException If reflection failed. |
| * @throws NoSuchMethodException If reflection failed. |
| * @throws IllegalArgumentException If reflection failed. |
| */ |
| @Benchmark |
| public void lookupNewInstance(Sources sources, Blackhole bh) throws InstantiationException, |
| IllegalAccessException, InvocationTargetException, NoSuchMethodException { |
| final Object[] nativeSeeds = sources.getNativeSeeds(); |
| final Class<?> implementingClass = sources.getImplementingClass(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(implementingClass.getConstructor(nativeSeeds[i].getClass()).newInstance(nativeSeeds[i])); |
| } |
| } |
| |
| /** |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createNullSeed(Sources sources, Blackhole bh) { |
| final RandomSource randomSource = sources.getRandomSource(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(RandomSource.create(randomSource, null)); |
| } |
| } |
| |
| /** |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createNativeSeed(Sources sources, Blackhole bh) { |
| final RandomSource randomSource = sources.getRandomSource(); |
| final Object[] nativeSeeds = sources.getNativeSeeds(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(RandomSource.create(randomSource, nativeSeeds[i])); |
| } |
| } |
| |
| /** |
| * Test the native seed with arrays truncated to length 1. This tests the speed |
| * of self-seeding. |
| * |
| * <p>This test is the same as {@link #createNativeSeed(Sources, Blackhole)} if |
| * the random source native seed is not an array. |
| * |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createSelfSeed(Sources sources, Blackhole bh) { |
| final RandomSource randomSource = sources.getRandomSource(); |
| final Object[] nativeSeeds1 = sources.getNativeSeeds1(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(RandomSource.create(randomSource, nativeSeeds1[i])); |
| } |
| } |
| |
| /** |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createLongSeed(Sources sources, Blackhole bh) { |
| final RandomSource randomSource = sources.getRandomSource(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(RandomSource.create(randomSource, LONG_SEEDS[i])); |
| } |
| } |
| |
| /** |
| * @param sources Source of randomness. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createByteArray(Sources sources, Blackhole bh) { |
| final RandomSource randomSource = sources.getRandomSource(); |
| final byte[][] byteSeeds = sources.getByteSeeds(); |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(RandomSource.create(randomSource, byteSeeds[i])); |
| } |
| } |
| |
| /** |
| * @param sizes Size of {@code int[]} seed. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createIntArraySeed(IntSizes sizes, Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(SeedFactory.createIntArray(sizes.getSize())); |
| } |
| } |
| |
| /** |
| * @param sizes Size of {@code long[]} seed. |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createLongArraySeed(LongSizes sizes, Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| bh.consume(SeedFactory.createLongArray(sizes.getSize())); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createSingleIntegerSeed(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| // This has to be boxed to an object |
| bh.consume(Integer.valueOf(SeedFactory.createInt())); |
| } |
| } |
| |
| /** |
| * @param bh Data sink. |
| */ |
| @Benchmark |
| public void createSingleLongSeed(Blackhole bh) { |
| for (int i = 0; i < SEEDS; i++) { |
| // This has to be boxed to an object |
| bh.consume(Long.valueOf(SeedFactory.createLong())); |
| } |
| } |
| } |