Why can't I see the same performance improvement on both the JVM 32 and 64 bits?

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) -> {});
}
+4
1

, , , . takewhile Integer, isPrime int.

, , .. 10_000 , 100_000 1_000_000. , JVM , , .

, , 64Bit JVM, , , , max , JVM , .


, . () -> res collect, , , theres - , filter.

, , , , . :

public static List<Integer> primesBest(int max) {
    BitSet prime=new BitSet();
    prime.set(1, max>>1);
    for(int i=3; i<max; i+=2)
        if(prime.get((i-1)>>1))
            for(int b=i*3; b<max; b+=i*2) prime.clear((b-1)>>1);
    return IntStream.concat( IntStream.of(2),
        prime.stream().map(i->i+i+1)).boxed().collect(Collectors.toList());
}

"", Stream , List<Integer>. 10 , 10_000, 50 1_000_000. , 10%, 20% .

, Stream API. , Stream API.

+3

All Articles