Skip to content

Commit d7cca3f

Browse files
authored
Feature/bael 5176 random number generators (eugenp#11641)
* BAEL-5176: Add simple test * BAEL-5176: Add benchmark runner * BAEL-5176: Update examples * BAEL-5176: Refactor * BAEL-5176: Refactor * BAEL-5176: Refactor
1 parent c9a9a70 commit d7cca3f

10 files changed

Lines changed: 295 additions & 0 deletions

File tree

core-java-modules/core-java-17/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
<compilerArgs>--enable-preview</compilerArgs>
2828
<source>${maven.compiler.source.version}</source>
2929
<target>${maven.compiler.target.version}</target>
30+
<annotationProcessorPaths>
31+
<path>
32+
<groupId>org.openjdk.jmh</groupId>
33+
<artifactId>jmh-generator-annprocess</artifactId>
34+
<version>${jmh-generator.version}</version>
35+
</path>
36+
</annotationProcessorPaths>
3037
</configuration>
3138
</plugin>
3239
<plugin>
@@ -49,6 +56,20 @@
4956
</plugins>
5057
</build>
5158

59+
<dependencies>
60+
<dependency>
61+
<groupId>org.openjdk.jmh</groupId>
62+
<artifactId>jmh-core</artifactId>
63+
<version>${jmh-core.version}</version>
64+
</dependency>
65+
<dependency>
66+
<groupId>org.openjdk.jmh</groupId>
67+
<artifactId>jmh-generator-annprocess</artifactId>
68+
<version>${jmh-generator.version}</version>
69+
<scope>test</scope>
70+
</dependency>
71+
</dependencies>
72+
5273
<properties>
5374
<maven.compiler.source.version>17</maven.compiler.source.version>
5475
<maven.compiler.target.version>17</maven.compiler.target.version>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import org.openjdk.jmh.annotations.Benchmark;
4+
import org.openjdk.jmh.annotations.BenchmarkMode;
5+
import org.openjdk.jmh.annotations.Mode;
6+
import org.openjdk.jmh.annotations.OutputTimeUnit;
7+
8+
import java.util.concurrent.TimeUnit;
9+
import java.util.random.RandomGenerator;
10+
11+
public class BenchmarkRunner {
12+
13+
public static void main(String[] args) throws Exception {
14+
org.openjdk.jmh.Main.main(args);
15+
}
16+
17+
@Benchmark
18+
@BenchmarkMode(Mode.AverageTime)
19+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
20+
public static void testL128X1024MixRandom() {
21+
generateRandomNumbers(RandomGenerator.of("L128X1024MixRandom"));
22+
}
23+
24+
@Benchmark
25+
@BenchmarkMode(Mode.AverageTime)
26+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
27+
public static void testL128X128MixRandom() {
28+
generateRandomNumbers(RandomGenerator.of("L128X128MixRandom"));
29+
}
30+
31+
@Benchmark
32+
@BenchmarkMode(Mode.AverageTime)
33+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
34+
public static void testL128X256MixRandom() {
35+
generateRandomNumbers(RandomGenerator.of("L128X256MixRandom"));
36+
}
37+
38+
@Benchmark
39+
@BenchmarkMode(Mode.AverageTime)
40+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
41+
public static void testL32X64MixRandom() {
42+
generateRandomNumbers(RandomGenerator.of("L32X64MixRandom"));
43+
}
44+
45+
@Benchmark
46+
@BenchmarkMode(Mode.AverageTime)
47+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
48+
public static void testL64X1024MixRandom() {
49+
generateRandomNumbers(RandomGenerator.of("L64X1024MixRandom"));
50+
}
51+
52+
@Benchmark
53+
@BenchmarkMode(Mode.AverageTime)
54+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
55+
public static void testL64X128MixRandom() {
56+
generateRandomNumbers(RandomGenerator.of("L64X128MixRandom"));
57+
}
58+
59+
@Benchmark
60+
@BenchmarkMode(Mode.AverageTime)
61+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
62+
public static void testL64X128StarStarRandom() {
63+
generateRandomNumbers(RandomGenerator.of("L64X128StarStarRandom"));
64+
}
65+
66+
@Benchmark
67+
@BenchmarkMode(Mode.AverageTime)
68+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
69+
public static void testL64X256MixRandom() {
70+
generateRandomNumbers(RandomGenerator.of("L64X256MixRandom"));
71+
}
72+
73+
@Benchmark
74+
@BenchmarkMode(Mode.AverageTime)
75+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
76+
public static void testRandom() {
77+
generateRandomNumbers(RandomGenerator.of("Random"));
78+
}
79+
80+
@Benchmark
81+
@BenchmarkMode(Mode.AverageTime)
82+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
83+
public static void testSecureRandom() {
84+
generateRandomNumbers(RandomGenerator.of("SecureRandom"));
85+
}
86+
87+
@Benchmark
88+
@BenchmarkMode(Mode.AverageTime)
89+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
90+
public static void testSplittableRandom() {
91+
generateRandomNumbers(RandomGenerator.of("SplittableRandom"));
92+
}
93+
94+
@Benchmark
95+
@BenchmarkMode(Mode.AverageTime)
96+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
97+
public static void testXoroshiro128PlusPlus() {
98+
generateRandomNumbers(RandomGenerator.of("Xoroshiro128PlusPlus"));
99+
}
100+
101+
@Benchmark
102+
@BenchmarkMode(Mode.AverageTime)
103+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
104+
public static void testXoshiro256PlusPlus() {
105+
generateRandomNumbers(RandomGenerator.of("Xoshiro256PlusPlus"));
106+
}
107+
108+
private static void generateRandomNumbers(RandomGenerator generator) {
109+
generator.nextLong();
110+
generator.nextInt();
111+
generator.nextFloat();
112+
generator.nextDouble();
113+
}
114+
115+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import java.util.Comparator;
4+
import java.util.random.RandomGenerator;
5+
import java.util.random.RandomGeneratorFactory;
6+
7+
public class GeneratorFactory {
8+
9+
public static void main(String[] args) {
10+
System.out.println("Group\tName\tJumpable?\tSplittable?");
11+
RandomGeneratorFactory.all()
12+
.sorted(Comparator.comparing(RandomGeneratorFactory::name))
13+
.forEach(factory -> System.out.println(String.format("%s\t%s\t%s\t%s",
14+
factory.group(),
15+
factory.name(),
16+
factory.isJumpable(),
17+
factory.isSplittable())));
18+
}
19+
20+
public static int getRandomInt(RandomGenerator generator, int bound) {
21+
return generator.nextInt(bound);
22+
}
23+
24+
public static RandomGenerator getDefaultGenerator() {
25+
return RandomGeneratorFactory.getDefault().create();
26+
}
27+
28+
public static RandomGenerator getJumpableGenerator() {
29+
return RandomGeneratorFactory.all()
30+
.filter(RandomGeneratorFactory::isJumpable)
31+
.findAny()
32+
.map(RandomGeneratorFactory::create)
33+
.orElseThrow(() -> new RuntimeException("Error creating a generator"));
34+
}
35+
36+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import java.util.Random;
4+
5+
public class OldRandom {
6+
7+
public static int getRandomInt(int bound) {
8+
Random random = new Random();
9+
return random.nextInt(bound);
10+
}
11+
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.Executors;
8+
import java.util.random.RandomGenerator;
9+
import java.util.random.RandomGeneratorFactory;
10+
11+
public class SplittableGeneratorMultiThread {
12+
13+
public static List<Integer> generateNumbersInMultipleThreads() {
14+
List<Integer> numbers = Collections.synchronizedList(new ArrayList<>());
15+
ExecutorService executorService = Executors.newCachedThreadPool();
16+
17+
RandomGenerator.SplittableGenerator sourceGenerator = RandomGeneratorFactory
18+
.<RandomGenerator.SplittableGenerator>of("L128X256MixRandom")
19+
.create();
20+
21+
sourceGenerator.splits(20).forEach((splitGenerator) -> {
22+
executorService.submit(() -> {
23+
numbers.add(splitGenerator.nextInt(10));
24+
});
25+
});
26+
27+
return numbers;
28+
}
29+
30+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
module core.java {
22
requires jdk.incubator.vector;
33
requires jdk.incubator.foreign;
4+
requires jmh.core;
5+
requires jdk.unsupported;
6+
exports com.baeldung.randomgenerators.jmh_generated;
47
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
class GeneratorFactoryUnitTest {
8+
9+
@Test
10+
void givenDefaultGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
11+
int number = GeneratorFactory.getRandomInt(GeneratorFactory.getDefaultGenerator(), 10);
12+
assertThat(number).isNotNegative().isLessThan(10);
13+
}
14+
15+
@Test
16+
void givenJumpableGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
17+
int number = GeneratorFactory.getRandomInt(GeneratorFactory.getJumpableGenerator(), 10);
18+
assertThat(number).isNotNegative().isLessThan(10);
19+
}
20+
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.random.RandomGenerator;
6+
7+
import static org.assertj.core.api.Assertions.assertThat;
8+
9+
class GeneratorSelectionUnitTest {
10+
11+
@Test
12+
void givenDefaultGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
13+
RandomGenerator generator = RandomGenerator.getDefault();
14+
int number = generator.nextInt(10);
15+
assertThat(number).isNotNegative().isLessThan(10);
16+
}
17+
18+
@Test
19+
void givenSpecificGenerator_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
20+
RandomGenerator generator = RandomGenerator.of("L128X256MixRandom");
21+
int number = generator.nextInt(10);
22+
assertThat(number).isNotNegative().isLessThan(10);
23+
}
24+
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
class OldRandomUnitTest {
8+
9+
@Test
10+
void givenOldRandomApi_whenGeneratingAnInt_thenIntInRangeIsGenerated() {
11+
int number = OldRandom.getRandomInt(10);
12+
assertThat(number).isNotNegative().isLessThan(10);
13+
}
14+
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.baeldung.randomgenerators;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.List;
6+
7+
import static org.assertj.core.api.Assertions.assertThat;
8+
9+
class SplittableGeneratorMultiThreadUnitTest {
10+
11+
@Test
12+
void givenSplittableGenerator_whenUsingMultipleThreads_thenListOfIntsIsGenerated() {
13+
List<Integer> numbers = SplittableGeneratorMultiThread.generateNumbersInMultipleThreads();
14+
assertThat(numbers).hasSize(20).allMatch(number -> number >= 0 && number <= 10);
15+
}
16+
17+
}

0 commit comments

Comments
 (0)