Wednesday, April 5, 2023

Java 8 Parallel Stream Example? How to improve performance by using parallelStream() in Java?

Hello guys, If you have been coding and programming in Java for a long time then you know that how hard it is to make an algorithm to run in parallel. You need to create multiple threads, make sure that they are properly synchronized and then need to co-ordinate between them to make it faster. But from Java 8, you can use parallel streams to improver performance of your CPU intensive algorithms without breaking your head over synchronization and threads. The Stream API allows you to run the stream operation in parallel by just calling the parallelStream() method. This is as simple as it can be to make your code take advantage of CPU power and run faster, and make your algorithm parallel and concurrent. You don't need to worry about creating or starting threads or coordinating between them. Just call this method and everything is done for you.

Java developer have been asking for long for simple API to take advantage of modern multi-core CPU architecture and parallel stream is the simplest way to achieve that. While it's not the magic bullet or master key which can make every algorithm parallel and every code fast, there are many scenarios when parallel stream can really make a difference.

For example, I have used parallel algorithm to make API calls in parallel, filter values from huge collection and even reading data from database.

Let's take another example of sorting a list of 10 million integers in Java. I am sure this is a time-consuming job

// sequential sorting
long count = values.stream().sorted().count();

// parallel sorting
long count1 = values.parallelStream().sorted().count();

// Output
10000000
sequential sorting of 10000000 integers took: 7346 ms
10000000
parallel sorting of 10000000 integers took: 2435 ms

You can see the parallel version of the code is almost 3 times faster than the sequential ones and you achieve that my just using parallelStream() method instead of stream(), I bet it can get more simpler than this unless you ask ChatGPT to sort a list for you.

Also, Here is a nice diagram which explains how parallel stream works in Java:

Java 8 ParallelStream Example - Sequential vs Parallel Sorting  in Java





How to use parallel Stream in Java? Example

Here is a complete Java program of using parallel stream in Java, you can use this example to play around and learn parallel stream better

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
 
/**
* Java program to demonstrate how to use parallel streams in Java 8. Parallel
* streams allows you to leverage multi-threading for time consuming jobs e.g.
* sorting a very big list, or filtering contents from large list. In this
* example, we have a collection of 50 million integers and we are filtering all
* multiples of 31. You can see that parallel version of this filtering logic
* took almost 20 times less time then sequential version.
*
* @author Javin
*/
public class ParallelStreamDemo{
 
    public static void main(String args[]) throws IOException {
 
        // Setting up collection class
        final int MAX_ORDERS = 50000000; // 50 mn integers
        List values = new ArrayList<>(MAX_ORDERS);
        Random rand = new Random(System.nanoTime());
        for (int i = 0; i < MAX_ORDERS; i++) {
            Integer number = rand.nextInt();
            values.add(number);
        }
 
        // Starting sequential filtering
        long startTime = System.nanoTime();
 
        long count = values.stream().filter(i -> i % 31 == 0).count();
        // long count = values.stream().sorted().count(); 
        //uncomment to test sorting
        System.out.println(count);
 
        long endTime = System.nanoTime();
 
        long timeTakenInMillis = TimeUnit.NANOSECONDS
                                         .toMillis(endTime - startTime);
        System.out.println(String.format("Sequential filtering took: %d ms",
                                          timeTakenInMillis));
 
 
        // Starting parallel filtering of Collection
        long start = System.nanoTime();
 
        long count1 = values.parallelStream().filter(i -> i % 31 == 0).count();
        // long count1 = values.parallelStream().sorted().count(); 
        //uncomment to test sorting
        System.out.println(count1);
 
        long end = System.nanoTime();
 
        long elapsed = TimeUnit.NANOSECONDS.toMillis(end - start);
        System.out.println(String.format("parallel filtering took: %d ms",
                            elapsed));
 
    }
 
}
 
Output
1612721
sequential filtering took: 7462 ms
1612721
parallel filtering took: 392 ms

That's all about how to use parallel streams in Java. You can see that it reduces processing time up to 20% depending upon the size of the collection. From my limited experience I can say that parallel stream is a great tool to improve the performance for CPU intensive task like you want to filter certain values from a huge collection of values, you can use parallel stream to do it faster.

Other Java 8 Lambda and Stream Tutorials for you
  • How to filter Collection using Streams in Java 8 (check here)
  • How to implement Comparator using lambda expression (see here)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • How to use Stream class in Java 8 (tutorial)
  • Top 5 Books to Learn Java 8 (read here)
  • How to use filter() method in Java 8 (tutorial)
  • How to use Stream API in Java 8 (learn here)
  • How to use forEach() method in Java 8 (example)
  • Understanding Default methods of Java 8 (learn here)
  • How to convert List to Map in Java 8 (solution)
  • How to join String in Java 8 (example)
  • How to use peek() method in Java 8 (example)
  • 10 Example of Stream API in Java? (stream examples)
  • 8 Best Lambda and Functional Programming courses (best courses)

Thanks for reading this article so far. If you like these Java 8 Parallel Stream examples then please share them with your friends and colleagues. If you have any questions or feedback about this Java 8 tutorial then please drop a note.   

P. S. - If you like the Java 8 Stream API and want to learn Stream in depth and looking for resources then you can also checkout this list of best Java collections and Stream online courses to dig deeper. This list contains best online courses to learn Stream API in depth. 

2 comments:

  1. When i try to run this pgm, i get below error on line #35. modulas operator in lambda. any idea?

    ReplyDelete
  2. typecast to int from Java.lang.Object type variable in expression - filter( i -> (int)i % 31 ==0)

    ReplyDelete