I tested two different approaches ( primes()and primesOpt()) for collecting the first N primes using Java 8 IntStream. I brought these examples from chapter 6 of Java 8 in action . You can get the source code from this gist Primes.java and this pom. xml to build it with Maven and JMH integration. (you can copy pom.xmlto the project folder and Primes.javato src\main\java\primesand build it with the command:. mvn clean installAfter that, you can run the test with:) java -jar target\benchmarks.jar.
The first example (method primes()) is a simple algorithm for collecting N primes in List<Integer>. And the second method ( primesOpt()) is an advanced approach that only checks divisions by previous primes.
I am testing both implementations with JMH to calculate a List<Integer>prime numbers up to a maximum of 10000:
@Benchmark
public int testPrimes() {
return primes(10_000).size();
}
@Benchmark
public int testPrimesOpt() {
return primesOpt(10_000).size();
}
And I got different accelerations depending on the JVM architecture. In 64-bit JVMs, I observe acceleration of 25% for primesOpt()the standard version primes(), while for 32-bit JVMs there are no accelerations.
Results for JRE 1.8.0_91-b14 64-bit:
Benchmark Mode Cnt Score Error Units
Primes.testPrimes thrpt 50 269,278 ± 15,922 ops/s
Primes.testPrimesOpt thrpt 50 341,861 ± 25,413 ops/s
Results for JRE 1.8.0_91-b14 32-bit:
Benchmark Mode Cnt Score Error Units
Primes.testPrimes thrpt 200 105,388 ± 2,741 ops/s
Primes.testPrimesOpt thrpt 200 103,015 ± 2,035 ops/s
Intel I7 Cpu, , 2 4 . , 4 . JVM 1,8.0_91-b14, Windows 7. 1024 ( -Xms1024M). .
- , 32- JVM ?
primes() :
public static boolean isPrime(int n) {
int root = (int) Math.sqrt(n);
return IntStream
.rangeClosed(2, root)
.noneMatch(div -> n%div == 0);
}
public static List<Integer> primes(int max) {
return IntStream
.range(2, max)
.filter(Primes::isPrime)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}
primesOpt() :
public static boolean isPrimeOpt(List<Integer> primes, int n) {
int root = (int) Math.sqrt(n);
return takeWhile(primes, root)
.stream()
.noneMatch(div -> n%div == 0);
}
public static List<Integer> takeWhile(List<Integer> src, int max) {
int i;
for(i = 0; i < src.size() && src.get(i) <= max; i++) {}
return src.subList(0, i);
}
public static List<Integer> primesOpt(int max) {
ArrayList<Integer> res = new ArrayList<>();
return IntStream
.range(2, max)
.filter(n -> Primes.isPrimeOpt(res, n))
.collect(() -> res, ArrayList::add, (l1, l2) -> {});
}