我正在测试一些Java8流API代码,但是我不知道这是怎么回事。

我在考虑ParallelStream及其工作原理,并进行了一些比较。
进行大迭代的两种不同方法添加了32.768.000 BigDecimals,一种使用ParallelStream,另一种使用常规迭代。我进行了一次测试,知道它是无效的,但是有些事情引起了我的注意。

测试是:

并行流:

private static void sumWithParallelStream() {
    BigDecimal[] list = new BigDecimal[32_768_000];
    BigDecimal total = BigDecimal.ZERO;
    for (int i = 0; i < 32_768_000; i++) {
        list[i] = new BigDecimal(i);
    }
    total = Arrays.asList(list).parallelStream().reduce(BigDecimal.ZERO, BigDecimal::add);
    System.out.println("Total: " + total);
}

普通代码:
private static void sequenceSum() {
    BigDecimal total = BigDecimal.ZERO;
    for (int i = 0; i < 32_768_000; i++) {
        total = total.add(new BigDecimal(i));
    }
    System.out.println("Total: " + total);
}

输出为:
Total: 536870895616000
sumWithParallelStream(): 30502 ms

Total: 536870895616000
sequenceSum(): 271 ms

然后我尝试删除parallelStream:
 private static void sumWithParallelStream() {
    BigDecimal[] list = new BigDecimal[32_768_000];
    BigDecimal total = BigDecimal.ZERO;
    for (int i = 0; i < 32_768_000; i++) {
        list[i] = new BigDecimal(i);
        total = total.add(list[i]);
    }
    System.out.println("Total: " + total);
}

请注意,sequenceSum()方法与相同

新的输出:
Total: 536870895616000
sumWithParallelStream(): 13487 ms

Total: 536870895616000
sequenceSum(): 879 ms

我进行了这些更改,多次添加和删除了parallelStream方法,并且sequenceSum()的结果从不改变,在其他方法上使用200时总是与parallelStream有关,而在不使用时则与800有关。在Windows和Ubuntu中进行测试。

最后,对我来说还有两个问题,为什么在第一种方法上使用parallelStream会对第二种方法产生影响?为什么在数组上存储BigDecimals会使第一种方法变得太慢(从800 ms13000 ms)?

最佳答案

在第一个示例中,您要分配32,768,000个元素的数组,然后在其上进行流式传输。不需要数组分配和内存获取,这可能会使方法变慢。

IntStream.range(0, limit).parallel()
   .mapToObj(BigDecimal::new)
   .reduce(BigDecimal.ZERO, BigDecimal::add);

10-04 17:26