java - 如果增加迭代次数,顺序流比并行流更快

标签 java java-8 parallel-processing java-stream

我使用最后的示例代码来衡量性能。

如果我调用 checkPerformanceResult 方法并将参数 numberOfTimes 设置为 100,则并行流的性能显着优于顺序流(sequential=346,parallel=78)。

如果我将参数设置为 1000,顺序流的性能明显优于并行流(sequential=3239,parallel=9337)。

我运行了很多次,结果都是一样的。

有人可以向我解释一下这种行为以及这里到底发生了什么吗?

public class ParallelStreamExample {
    public static long checkPerformanceResult(Supplier<Integer> s, int numberOfTimes) {
        long startTime = System.currentTimeMillis();
        for(int i = 0; i < numberOfTimes; i++) {

           s.get();
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

    public static int sumSequentialStreamThread() {
        IntStream.rangeClosed(1, 10000000).sum();
        return 0;
    }

    public static int sumParallelStreamThread() {
        IntStream.rangeClosed(1, 10000000)
                .parallel().sum();
        return 0;
    }

    public static void main(String[] args) {
        System.out.println(checkPerformanceResult(ParallelStreamExample::sumSequentialStreamThread, 1000));
        System.out.println("break");
        System.out.println(checkPerformanceResult(ParallelStreamExample::sumParallelStreamThread, 1000));
    }
}

最佳答案

使用线程并不总是能让代码运行得更快

当使用几个线程时,总是存在管理每个线程的开销(通过操作系统为每个线程分配 CPU 时间,管理在上下文切换等情况下需要运行的下一行代码......)

在本例中

sumParallelStreamThread中创建的每个线程在内存操作中都执行非常简单的操作(调用返回数字的函数)。

因此,sumSequentialStreamThreadsumParallelStreamThread 之间的区别在于,在 sumParallelStreamThread 中,每个简单操作都有创建线程并运行它的开销(假设后台没有发生任何线程优化)。

sumSequentialStreamThread 执行相同的操作,而无需管理所有线程的开销,这就是它运行速度更快的原因。

何时使用线程

使用线程最常见的用例是当您需要执行大量 I/O 任务时。

什么被视为 I/O 任务?

这取决于几个因素,你可以找到关于它的辩论here 。 但我认为一般来说人们会同意向某个地方发出 HTTP 请求或执行数据库查询可以被视为 I/O 操作。

为什么更合适?

因为 I/O 操作通常需要一段时间来等待与之相关的响应。 例如,在查询数据库时,执行查询的线程将等待数据库返回响应(即使不到半秒),而该线程正在等待另一个线程可以执行其他操作,这就是我们可以获得性能的地方。

我发现通常在不同线程中运行仅涉及 RAM 内存和 CPU 操作的任务会使代码运行速度比单个线程慢。

基准讨论

关于评论中的基准评论,我不确定它们是否正确,但在这种情况下,我会根据任何分析工具(或只是使用它开始)仔细检查我的基准,例如 JProfilerYoutKit它们通常非常准确。

关于java - 如果增加迭代次数,顺序流比并行流更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58142949/

相关文章:

java - 将 JTextField 替换为 Java Swing 中的一行

java - STS软件在哪些位置隐藏了JVM选项?使用STS时,如何使Java Hotspot MaxPermSize警告消失?

PHP fork 处理MySQL数据库无冲突

python - 使用 cython 并行化 python 循环 numpy.searchsorted

java - 在操作栏中显示列表 fragment

java - 如何在Hadoop中加载 native 库

java - Tomcat 7 找不到我的类抛出 javax.el.E​​LException : java. lang.NoClassDefFoundError

java-8 - 具有值映射函数生成列表的java 8列表分组

java - 优雅地组合两个列表的元素,使它们在某个属性值上是唯一的?

C# 事件 : How to process event in a parallel manner