-1

I'm doing some experiments with streams. More specific I would like to compare standard streams to parallel streams. But, I experience very slow response time using parallel compared to standard streams. This strange because I Expected the opposite. Here's the test code I wrote for the experiment. Any suggestions are welcome.

package streamsExamples;

import java.util.OptionalDouble;
import java.util.stream.*;
import java.util.*;

import static java.util.stream.IntStream.of;


public class ParallelSpeedTest {
  private static OptionalDouble optionalDouble;
  private final static long LIMIT = 100000000;
  private static Random random = new Random();
  private static ArrayList<Integer>  list= new ArrayList<Integer>();
  public static void main(String[] args) {
    long begin, end;

    for(long i = 0; i < LIMIT; i++){
        list.add(random.nextInt());
    }
    begin = System.currentTimeMillis();
    streamTest();
    end = System.currentTimeMillis();
    System.out.println("Stream: " +(end - begin));

    begin = System.currentTimeMillis();
    parallelStreamTest();
    end = System.currentTimeMillis();
    System.out.println("Parallel Stream: " +(end - begin));
  }

  public static void streamTest() {
    optionalDouble = IntStream
            .generate(new Random()::nextInt)
            .limit(LIMIT)
            .average();

  }

  public static void parallelStreamTest(){
    optionalDouble = IntStream
            .generate(new Random()::nextInt)
            .parallel()
            .limit(100000000)
            .average();
     }
  }
Mat
  • 202,337
  • 40
  • 393
  • 406
  • I think the limit destroys the performance boost.... from the javaDoc of .limit "While limit() is generally a cheap operation on sequentialstream pipelines, it can be quite expensive on ordered parallel pipelines,especially for large values of maxSize, since limit(n)is constrained to return not just any n elements, but the first n elements in the encounter order. " ... and of course you have to do some kind of warmup run before – JavaMan Nov 14 '20 at 10:43
  • 1
    [How do I write a correct micro-benchmark in Java](https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) – Michał Krzywański Nov 14 '20 at 12:02
  • The same problem as [here](https://stackoverflow.com/questions/23663178/inefficient-threads-in-java): your threads compete for the same instance of Random – apangin Nov 14 '20 at 16:07

1 Answers1

0

Just because I was interested... I've created an example where you can see that parallelStream is faster (for the quite same thing that you are doing)

And that both, sequential and parallel Streams get fast if you call them again and again, due to compiler optimizations.

import java.util.OptionalDouble;
import java.util.Random;
import java.util.stream.IntStream;

public class ParallelSpeedTest {
    private static OptionalDouble optionalDouble;
    private final static int LIMIT = 100000000;
    private static Random random = new Random();
    private static int[] arr = new int[LIMIT];

    public static void main(String[] args) {
        long begin, end;

        Random r = new Random(42);
        for (int i = 0; i < LIMIT; i++) {
            arr[i] = r.nextInt(10);
        }

        for (int i = 0; i < 100; i++) {
            System.out.println("run nr "+i);

            begin = System.currentTimeMillis();
            streamTest();
            end = System.currentTimeMillis();
            System.out.println("Stream: " + (end - begin));

            begin = System.currentTimeMillis();
            parallelStreamTest();
            end = System.currentTimeMillis();
            System.out.println("Parallel Stream: " + (end - begin));

            System.out.println();
        }
    }

    public static void streamTest() {
        optionalDouble = IntStream.of(arr).average();
    }

    public static void parallelStreamTest() {
        optionalDouble = IntStream.of(arr).parallel().average();
    }
}

Output:

run nr 0
Stream: 62
Parallel Stream: 26
...
run nr 10
Stream: 39
Parallel Stream: 17
...

run nr 20
Stream: 42
Parallel Stream: 18
...
run nr 30
Stream: 42
Parallel Stream: 16
...
run nr 50
Stream: 42
Parallel Stream: 17
...
run nr 99
Stream: 43
Parallel Stream: 19

funny thing... if I let it run for longer parallel will get slower again (no idea why)
output run nr 500
Stream: 41
Parallel Stream: 94
JavaMan
  • 1,142
  • 12
  • 22