Close

Java 8 Parallel and Sequential streams performance Comparison

[Last Updated: Dec 7, 2016]

Java Java 8 Streams 

This example demonstrates the performance difference between Java 8 parallel and sequential streams.


API used

Stream#generate(Supplier<T> s): Returns an instance of Stream <T> which is infinite, unordered and sequential by default. Each element is generated by the provided Supplier.

BaseStream#parallel(): Returns an equivalent stream that is parallel. If this stream is already parallel then returns itself.

BaseStream#sequential(): Returns an equivalent stream that is sequential. If this stream is already sequential then returns itself.

Stream#map(Function mapper): Returns a stream consisting of the results of applying the given function to the elements of this stream. This is an intermediate operation.

Stream#reduce(T identity, BinaryOperator<T> accumulator) Performs the provided accumulator operation ( BinaryOperator<T>) on each two individual elements of the streams. and returns the reduced value T. The identity is the initial value to start with.

Stream#limit(long maxSize): Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.


Example

package com.logicbig.example;


import java.math.BigDecimal;
import java.util.stream.Stream;

public class ParallelStreamExample {

public static void main (String[] args) {
long parallelTime = 0;
long sequentialTime = 0;
long time;
BigDecimal sum;

for (int i = 0; i <= 5; i++) {

time = System.currentTimeMillis();
sum = Stream.generate(() -> new BigDecimal(Math.random() * 10000))
.limit(1000000)
.parallel()
.map(b -> b.multiply(BigDecimal.TEN))
.reduce(BigDecimal.ZERO, (a, b) -> a.add(b));

if (i > 0) {
parallelTime += (System.currentTimeMillis() - time);
}

time = System.currentTimeMillis();
sum = Stream.generate(() -> new BigDecimal(Math.random() * 10000))
.limit(1000000)
.sequential()
.map(b -> b.multiply(BigDecimal.TEN))
.reduce(BigDecimal.ZERO,(a, b) -> a.add(b));
if (i > 0) {
sequentialTime += (System.currentTimeMillis() - time);
}

}

System.out.println("average time for parallel calc " + (parallelTime / 5));
System.out.println("average time for sequential calc " + (sequentialTime / 5));
}
}


In above example we are taking the average elapsed time of 5 iteration for each parallel and sequential calculation using streams. We are skipping the first iteration to avoid the doubt of cold start.


Output:

average time for parallel calc 183
average time for sequential calc 498

The output might be different on different machines. A machine with multiple cores will give a big difference.


The Java version I used

c:\>java -version

java version "1.8.0_65"

Java(TM) SE Runtime Environment (build 1.8.0_65-b17)

Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

System info:

C:\>systeminfo

...

OS Name: Microsoft Windows 8.1

OS Version: 6.3.9600 N/A Build 9600

OS Configuration: Standalone Workstation

OS Build Type: Multiprocessor Free

.....

System Type: x64-based PC

Processor(s): 1 Processor(s) Installed.

[01]: Intel64 Family 6 Model 71 Stepping 1 GenuineIntel ~2701 Mhz

....

Total Physical Memory: 16,299 MB

Available Physical Memory: 8,893 MB

Virtual Memory: Max Size: 18,752 MB

Virtual Memory: Available: 9,204 MB

Virtual Memory: In Use: 9,548 MB


See Also