为什么并行流速较慢? [英] Why is parallel stream slower?

查看:117
本文介绍了为什么并行流速较慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩无限的流,并制作了这个程序进行基准测试。基本上,您提供的数字越大,完成的速度就越快。但是,我惊讶地发现,与顺序流相比,使用parellel流导致性能呈指数级下降。直觉上,人们会期望在多线程环境中生成和评估无限的随机数流,但似乎并非如此。这是为什么?

I was playing around with infinite streams and made this program for benchmarking. Basically the bigger the number you provide, the faster it will finish. However, I was amazed to find that using a parellel stream resulted in exponentially worse performance compared to a sequential stream. Intuitively, one would expect an infinite stream of random numbers to be generated and evaluated much faster in a multi-threaded environment, but this appears not to be the case. Why is this?

    final int target = Integer.parseInt(args[0]);
    if (target <= 0) {
        System.err.println("Target must be between 1 and 2147483647");
        return;
    }

    final long startTime, endTime;
    startTime = System.currentTimeMillis();

    System.out.println(
        IntStream.generate(() -> new Double(Math.random()*2147483647).intValue())
        //.parallel()
        .filter(i -> i <= target)
        .findFirst()
        .getAsInt()
    );

    endTime = System.currentTimeMillis();
    System.out.println("Execution time: "+(endTime-startTime)+" ms");


推荐答案

我完全同意其他评论和答案,但确实如果目标非常低,你的测试表现得很奇怪。在我的适度笔记本电脑上,当给出非常低的目标时,并行版本平均慢约60倍。这种极端的差异无法用流API中的并行化开销来解释,所以我也很惊讶:-)。 IMO的罪魁祸首在于:

I totally agree with the other comments and answers but indeed your test behaves strange in case that the target is very low. On my modest laptop the parallel version is on average about 60x slower when very low targets are given. This extreme difference cannot be explained by the overhead of the parallelization in the stream APIs so I was also amazed :-). IMO the culprit lies here:

Math.random()

在内部,此调用依赖于 java.util.Random 的全局实例。在随机文档中写道:

Internally this call relies on a global instance of java.util.Random. In the documentation of Random it is written:


java.util.Random的实例是线程安全的。但是,并发
跨线程使用相同的java.util.Random实例可能会遇到
争用并因此导致性能不佳。请考虑在多线程设计中使用
ThreadLocalRandom。

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.

所以我认为并行执行的性能确实比较差顺序一个是由随机的线程争用而不是任何其他开销来解释的。如果您使用 ThreadLocalRandom (根据文档中的建议),那么性能差异将不会那么显着。另一种选择是实施更高级的数字供应商。

So I think that the really poor performance of the parallel execution compared to the sequential one is explained by the thread contention in random rather than any other overheads. If you use ThreadLocalRandom instead (as recommended in the documentation) then the performance difference will not be so dramatic. Another option would be to implement a more advanced number supplier.

这篇关于为什么并行流速较慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆