The problem is as follows: "Find prime numbers in the given interval". The algorithm is not that important. I came up with:
public class Prime { public static void main(String[] args) throws Exception { final int threshold = 50_000_000; final long start = System.currentTimeMillis(); final ListPrinted result:candidates = IntStream.range(2, threshold).boxed().collect(Collectors.toList()); final List primeNumbers = candidates.stream().filter(Prime::isPrime).collect(Collectors.toList()); System.out.println("Execution time: " + System.currentTimeMillis() - start); System.out.println("Size: " + primeNumbers.size()); } private static boolean isPrime(final int candidate) { for (int i = 2; i * i <= candidate; ++i) { if (candidate % i == 0) { return false; } } return true; } }
Execution time: 55166 Size: 3001134The code is quite clean. However, it is executed sequentially and I have 4-cores (4.5 GHz each) - Core i5 Sandy Bridge - under the hood. Can we improve something? Of course we can! There is a new stream() API in Java 8 that allows for parallel processing. Just a small change to the code and we are set:
final ListThe output was:primeNumbers = candidates.parallelStream().filter(Prime::isPrime).collect(Collectors.toList());
Execution time: 16950 Size: 3001134Not so bad. parallelStream() uses default ForkJoin pool. Let's check the state of the threads:
4 threads are engaged in the computations: main thread and 3 workers. Can we obtain the result faster? How about using custom ForkJoin pool with 5 threads:
final ForkJoinPool forkJoinPool = new ForkJoinPool(5); final ListprimeNumbers = forkJoinPool.submit(() -> candidates.parallelStream().filter(Prime::isPrime).
The output:collect(Collectors.toList())).get();
Execution time: 15504 Size: 3001134The state of the threads:
Excellent example. Thanks :)
ReplyDelete