为什么IntStream.range(0,100000).parallel.foreach需要比循环更长的正常时间

我刚刚开始学习Java中的Streams和parallel,我想知道为什么正常for循环比在向数组添加项目时并行的IntStream花费更少的时间。

 package parallel; import java.util.stream.IntStream; public class Parallel { public static void main(String[] args) { final int[] intArray = new int[100000]; long startTime = System.currentTimeMillis(); IntStream.range(0, 100000).parallel().forEach(i -> intArray[i]=i); long endTime = System.currentTimeMillis(); System.out.println("Parallel time: " + (endTime-startTime)); final int[] intArray2 = new int[100000]; try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } startTime = System.currentTimeMillis(); for(int i = 0; i < 100000; i++){ intArray2[i] = i; } endTime = System.currentTimeMillis(); System.out.println("Non parallel time: " + (endTime-startTime)); } } 

得到这样的结果。

平行时间:110

非平行时间:7

您为每个元素执行的操作非常简单,它只是一个赋值,非常快。 在并行版本中,启动处理操作的多个线程会产生大量开销。 仅这一点可能已经花费的时间比非平行时非常简单的操作需要的时间长。

此外,在非并行版本中,值非常线性地写入arrays,对于许多CPU来说是最佳行为。 在并行版本中,你可能会遇到冲突,因为每个线程都试图写入同一个数组(虽然在不同的位置,但可能仍然在同一个缓存行上),并且当几个线程访问数组的不同部分时,你也可能会出现缓存未命中,这会减慢速度。

随着更昂贵的操作,并行版本的开销与总成本相比变得更小,这最终将导致比非并行情况更快的执行。