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 super T,? extends R> 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
|