Skip to content

Unleashing the Power of Parallel Streams in Functional Programming

Posted on:August 31, 2023 at 03:13 PM

Greetings, fellow explorers of the code realm! Today, we embark on a thrilling expedition into the world of parallel streams – a phenomenon that promises to accelerate our code execution and unlock the full potential of multi-core processors. Welcome back to another captivating chapter of our journey through functional programming.

Table of contents

Open Table of contents

Sections

Unveiling Parallel Streams: A Journey for Speed

Parallel streams offer us the magical ability to execute code faster, all without breaking a sweat. In this captivating lecture, we delve into the world of parallelism, where more resources work in harmony to achieve faster processing. In a world where multi-core processors are commonplace, our programs can be optimized to make the most of these available resources. This optimization allows us to harness the power of parallelism, where tasks can be accomplished simultaneously, unleashing new realms of efficiency.

Sequential vs. Parallel: Two Streams of Thought

Before we immerse ourselves in the world of parallel streams, let’s clarify the two ways in which streams can be processed: sequential and parallel. By default, the streams we create operate sequentially – each element processed in order, one after the other. However, in the realm of parallel streams, we unlock the potential of simultaneous processing, utilizing the multiple cores at our disposal.

The Ritual of Creating Parallel Streams

Brace yourselves, for we have two invocations to create parallel streams. The first is simple: rather than invoking the stream method, we use the parallelStream method to craft parallel streams right from the start. The second, equally enchanting method, involves converting a sequential stream into a parallel one. This is achieved by invoking the parallel method on an existing sequential stream. The beauty of this approach lies in its simplicity – a mere transformation of the stream state is enough to set the stage for parallel processing.

Unveiling the Performance Boost: Practical Example

To truly comprehend the power of parallel streams, let’s immerse ourselves in a practical demonstration. Imagine a realm where employees are meticulously managed, each with their own name and salary. In our enchanting example, we create a list of employees, summoning them forth through iterations. Our task is simple: count the number of employees with salaries exceeding a thousand units.

We venture into the realm of sequential streams first, counting the employees one by one. Then, we unleash the parallel streams, allowing multiple cores to engage in the task simultaneously. Behold as the execution time drastically reduces, a testament to the prowess of parallel processing.

Parallel streams offer speed and power, but their application requires careful consideration. The essence lies in ensuring that operations are stateless, non-interfering, and associative. These guidelines ensure that the parallel execution produces the same outcomes as sequential processing, regardless of the order or concurrency. It’s a delicate balance between harnessing the power of parallelism and maintaining the integrity of the results.

        long startTime;
        long endTime;

        List<Employee> list = new ArrayList<>();

        for (int i = 0; i < 100; i++) {
            list.add(new Employee("John", 20000));
            list.add(new Employee("Rohn", 3000));
            list.add(new Employee("Tom", 15000));
            list.add(new Employee("Bheem", 8000));
            list.add(new Employee("Shiva", 200));
            list.add(new Employee("Krishna", 50000));
        }


        startTime = System.currentTimeMillis();
        System.out.println("Performing Sequentially: "+list.stream()
                .filter(e -> e.getSalary()> 1000)
                .count());

        endTime = System.currentTimeMillis();

        System.out.println("Time taken with Sequential : "+(endTime - startTime));

        startTime = System.currentTimeMillis();
        System.out.println("Performing parallely: "+list.parallelStream()
                .filter(e -> e.getSalary()> 1000)
                .count());

        endTime = System.currentTimeMillis();

        System.out.println("Time taken with parallel : "+(endTime - startTime));

The Reality of Parallel Streams

While parallel streams offer a world of possibilities, they come with caveats. The complexity of parallel execution can sometimes outweigh the benefits, and not all operations will result in enhanced speed. It’s important to remember that parallelism is not a magic spell – it requires thoughtful consideration of the operation’s nature and the data at hand.

The Key Takeaway

As we conclude this enchanting lecture on parallel streams, remember this golden rule: seek parallelism when sequential processing becomes a bottleneck, but approach with caution and measure the impact. Parallel streams hold the potential to revolutionize the speed of execution, but their magic is most potent when wielded with wisdom and understanding.

You can find the repo for this section of the course Here