1

I compared performance for a simple "find max" logic in a 10 million integer array. The simple for loop performs much (at least 10 times better) than lambda and parallel stream version.

Could someone help me in understanding this counter intuitive behavior? I've a Quad core Intel i5 processor Dell E5530 laptop with Windows 7 professional installed, with 1.8.0_60 64 bit JVM.

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;

public class MaxFind
{
  private static final int CAPACITY = 10_000_000;

  public static void main(String[] args) throws Exception
  {
    List<Integer> numbers = new ArrayList<Integer>(CAPACITY);
    Random rand = new Random();

    long start = System.currentTimeMillis();
    for(int i=0; i<CAPACITY; i++)
        numbers.add(rand.nextInt());
    long end = System.currentTimeMillis();
    System.out.println("size of numbers: " + numbers.size() + ", time taken to populate: " + (end-start) + " milliseconds");

    start = System.currentTimeMillis();
    int maxNum = Integer.MIN_VALUE;

    //imperative approach
    for(int i=0; i<numbers.size(); i++)
        maxNum = Integer.max(numbers.get(i), maxNum);
    end = System.currentTimeMillis();

    System.out.println("Time taken to find the max value " + maxNum + " using normal for loop: " + (end-start) + " milliseconds.");

    start = System.currentTimeMillis();
    //lambda, parallel stream
    Optional<Integer> max = numbers.parallelStream().reduce(Integer::max);
    end = System.currentTimeMillis();
    System.out.println("Time taken to find the max value " + max.get() + " using lambda with parallel stream 1: " + (end-start) + " milliseconds.");

    start = System.currentTimeMillis();
    maxNum = numbers.parallelStream().reduce(Integer.MIN_VALUE, (a, b) -> Integer.max(a, b));
    end = System.currentTimeMillis();
    System.out.println("Time taken to find the max value " + max.get() + " using lambda with parallel stream 2: " + (end-start) + " milliseconds.");        
   }
}
RRM
  • 2,495
  • 29
  • 46
  • 3
    Because your imperative loop is using `int`, but the two parallel stream versions are using `Integer`, which means that have to keep boxing and unboxing. Change to `Integer maxNum`, and you'll actually be comparing apples to apples. FYI: You can get the `int` performance on streams by using `parallelStream().max(Comparator.naturalOrder())`. – Andreas Dec 03 '15 at 08:12
  • 2
    [How do I write a correct micro-benchmark in Java?](http://stackoverflow.com/q/504103/2711488) – Holger Dec 03 '15 at 09:01
  • 1
    @Andreas: or `.mapToInt(Integer::intValue).max()` to perform the operation with `int`s. But you’ll need roughly ten times the number of elements before noticing a difference with parallel streams… – Holger Dec 03 '15 at 09:30

0 Answers0