blob: 565fe39476a76d84d5985301fd7e56ddfc7a5791 [file] [log] [blame]
/*
* 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()));
}
}
}