并行流比 Java 中的流花费更多时间

问题描述

我正在学习 java stream api,我在代码中发现了这个问题。

这是我的代码

 long s = System.currentTimeMillis();
 IntStream.range(1,10).parallel().forEach( x ->{
      System.out.println( "Thread -> "+ Thread.currentThread().getName() +" "+ x );
 });
 long e = System.currentTimeMillis();
 System.out.println("Time taken "+ (e-s) + " ms");

 System.out.println("---------------------");

 s = System.currentTimeMillis();
 IntStream.range(1,10).forEach( x ->{
     System.out.println( "Thread -> "+ Thread.currentThread().getName() +" "+ x );
 });
 e = System.currentTimeMillis();
 System.out.println("Time taken "+ (e-s) + " ms");

这是输出

Thread -> main 6
Thread -> ForkJoinPool.commonPool-worker-7 2
Thread -> ForkJoinPool.commonPool-worker-7 5
Thread -> ForkJoinPool.commonPool-worker-13 1
Thread -> ForkJoinPool.commonPool-worker-11 4
Thread -> ForkJoinPool.commonPool-worker-3 3
Thread -> ForkJoinPool.commonPool-worker-15 9
Thread -> ForkJoinPool.commonPool-worker-9 7
Thread -> ForkJoinPool.commonPool-worker-5 8
Time taken using parallel stream 29 ms
-------------------------------------
Thread -> main 1
Thread -> main 2
Thread -> main 3
Thread -> main 4
Thread -> main 5
Thread -> main 6
Thread -> main 7
Thread -> main 8
Thread -> main 9
Time taken simple stream 1 ms

我在 sts 和 inteliJ IDE 上试过这段代码,结果是一样的。并行比顺序花费更长的时间。 我的jdk有问题吗?请提出建议。

解决方法

首先,做这种基准测试很困难。各种优化都是在代码执行过程中进行的。但在这种情况下,如果基准测试良好,我不会期望有太大不同的结果。

首先,并行化成本开销。您需要启动和停止线程,有时在某些点同步它们,在它们之间进行通信等。所以通常只有在有很多元素要处理并且需要为每个元素完成的工作时才值得付出努力是不平凡的。在您的情况下,两者都不正确。

其次,您正在输出到标准输出。 System.out 只允许一个线程同时输出一些东西。这样做是为了在多个线程尝试写入标准输出时输出不会被打乱太多。这意味着在您的情况下,所有线程基本上都会花费大量时间等待轮到它们写入。

所以,不,您的 JVM 没有任何问题。