Feature/bael 5176 random number generators (#11641)
* BAEL-5176: Add simple test * BAEL-5176: Add benchmark runner * BAEL-5176: Update examples * BAEL-5176: Refactor * BAEL-5176: Refactor * BAEL-5176: Refactor
This commit is contained in:
parent
ff081330bc
commit
8bf612c07a
|
@ -27,6 +27,13 @@
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>${maven.compiler.source.version}</source>
|
<source>${maven.compiler.source.version}</source>
|
||||||
<target>${maven.compiler.target.version}</target>
|
<target>${maven.compiler.target.version}</target>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh-generator.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -49,6 +56,20 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>${jmh-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh-generator.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source.version>17</maven.compiler.source.version>
|
<maven.compiler.source.version>17</maven.compiler.source.version>
|
||||||
<maven.compiler.target.version>17</maven.compiler.target.version>
|
<maven.compiler.target.version>17</maven.compiler.target.version>
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.random.RandomGenerator;
|
||||||
|
|
||||||
|
public class BenchmarkRunner {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL128X1024MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L128X1024MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL128X128MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L128X128MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL128X256MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L128X256MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL32X64MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L32X64MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL64X1024MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L64X1024MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL64X128MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L64X128MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL64X128StarStarRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L64X128StarStarRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testL64X256MixRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("L64X256MixRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("Random"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testSecureRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("SecureRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testSplittableRandom() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("SplittableRandom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testXoroshiro128PlusPlus() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("Xoroshiro128PlusPlus"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void testXoshiro256PlusPlus() {
|
||||||
|
generateRandomNumbers(RandomGenerator.of("Xoshiro256PlusPlus"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateRandomNumbers(RandomGenerator generator) {
|
||||||
|
generator.nextLong();
|
||||||
|
generator.nextInt();
|
||||||
|
generator.nextFloat();
|
||||||
|
generator.nextDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.random.RandomGenerator;
|
||||||
|
import java.util.random.RandomGeneratorFactory;
|
||||||
|
|
||||||
|
public class GeneratorFactory {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("Group\tName\tJumpable?\tSplittable?");
|
||||||
|
RandomGeneratorFactory.all()
|
||||||
|
.sorted(Comparator.comparing(RandomGeneratorFactory::name))
|
||||||
|
.forEach(factory -> System.out.println(String.format("%s\t%s\t%s\t%s",
|
||||||
|
factory.group(),
|
||||||
|
factory.name(),
|
||||||
|
factory.isJumpable(),
|
||||||
|
factory.isSplittable())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getRandomInt(RandomGenerator generator, int bound) {
|
||||||
|
return generator.nextInt(bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RandomGenerator getDefaultGenerator() {
|
||||||
|
return RandomGeneratorFactory.getDefault().create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RandomGenerator getJumpableGenerator() {
|
||||||
|
return RandomGeneratorFactory.all()
|
||||||
|
.filter(RandomGeneratorFactory::isJumpable)
|
||||||
|
.findAny()
|
||||||
|
.map(RandomGeneratorFactory::create)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Error creating a generator"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class OldRandom {
|
||||||
|
|
||||||
|
public static int getRandomInt(int bound) {
|
||||||
|
Random random = new Random();
|
||||||
|
return random.nextInt(bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.random.RandomGenerator;
|
||||||
|
import java.util.random.RandomGeneratorFactory;
|
||||||
|
|
||||||
|
public class SplittableGeneratorMultiThread {
|
||||||
|
|
||||||
|
public static List<Integer> generateNumbersInMultipleThreads() {
|
||||||
|
List<Integer> numbers = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
RandomGenerator.SplittableGenerator sourceGenerator = RandomGeneratorFactory
|
||||||
|
.<RandomGenerator.SplittableGenerator>of("L128X256MixRandom")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
sourceGenerator.splits(20).forEach((splitGenerator) -> {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
numbers.add(splitGenerator.nextInt(10));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
module core.java {
|
module core.java {
|
||||||
requires jdk.incubator.vector;
|
requires jdk.incubator.vector;
|
||||||
requires jdk.incubator.foreign;
|
requires jdk.incubator.foreign;
|
||||||
|
requires jmh.core;
|
||||||
|
requires jdk.unsupported;
|
||||||
|
exports com.baeldung.randomgenerators.jmh_generated;
|
||||||
}
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class GeneratorFactoryUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenDefaultGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
|
||||||
|
int number = GeneratorFactory.getRandomInt(GeneratorFactory.getDefaultGenerator(), 10);
|
||||||
|
assertThat(number).isNotNegative().isLessThan(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJumpableGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
|
||||||
|
int number = GeneratorFactory.getRandomInt(GeneratorFactory.getJumpableGenerator(), 10);
|
||||||
|
assertThat(number).isNotNegative().isLessThan(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class GeneratorSelectionUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenDefaultGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
|
||||||
|
RandomGenerator generator = RandomGenerator.getDefault();
|
||||||
|
int number = generator.nextInt(10);
|
||||||
|
assertThat(number).isNotNegative().isLessThan(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSpecificGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
|
||||||
|
RandomGenerator generator = RandomGenerator.of("L128X256MixRandom");
|
||||||
|
int number = generator.nextInt(10);
|
||||||
|
assertThat(number).isNotNegative().isLessThan(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class OldRandomUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenOldRandomApi_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
|
||||||
|
int number = OldRandom.getRandomInt(10);
|
||||||
|
assertThat(number).isNotNegative().isLessThan(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.randomgenerators;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class SplittableGeneratorMultiThreadUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSplittableGenerator_whenUsingMultipleThreads_thenListOfIntsIsGenerated() {
|
||||||
|
List<Integer> numbers = SplittableGeneratorMultiThread.generateNumbersInMultipleThreads();
|
||||||
|
assertThat(numbers).hasSize(20).allMatch(number -> number >= 0 && number <= 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue