1核心上的并行Java流

Sim*_*ang 0 java parallel-processing java-8 java-stream

假设我有一个天真的阶乘函数:

import java.util.stream.LongStream;

public class FactorialTest {

    static long factorial(long n, boolean parallel) {
        return (parallel
                ? LongStream.range(1, n).parallel()
                : LongStream.range(1, n))
                .reduce(1, (l, m) -> l * m);
    }

    public static void main(String[] args) {
        System.out.println(factorial(10, true));
    }
}
Run Code Online (Sandbox Code Playgroud)

我觉得即使在单逻辑核心机器上,多线程减少仍然比单线程更快.如何使用流API对其进行测试或解决此问题?

Stu*_*rks 5

在JDK 8上,并行流默认在公共fork-join池中执行,这在ForkJoinPool javadoc页面上有记录.此页面记录了一个系统属性java.util.concurrent.ForkJoinPool.common.parallelism,您可以设置该属性来控制公共池中的线程数(并行度).

要对需要相对较少时间的代码进行基准测试,我建议您使用JMH.这是一个开源的微基准测试工具,具有避免大多数基准测试陷阱的功能,例如死代码消除和JIT预热时间.

即便如此,10!(十阶乘)只有十次乘法,只需几纳秒.更糟糕的是,您将溢出一个很长的值,21!这仍然是一个非常短的工作量.在这些短时间内,我怀疑设置流的开销 - 串行或并行 - 将主导实际计算.但到底是什么,继续测量吧!在任何情况下,您可能都希望找到更重的工作量来进行基准测试.