Java Stream API:为什么区分顺序和并行执行模式?

流 javadoc

流管道可以按顺序执行,也可以并行执行。此执行模式是流的一个属性。创建流时,最初可以选择顺序执行或并行执行。

我的假设:

  1. 顺序/并行流之间没有功能差异。输出永远不会受到执行模式的影响。
  2. 由于性能提高,给定适当的内核数量和问题大小来证明开销合理,并行流始终是首选。
  3. 我们希望一次编写代码,并在任何地方运行,而不必关心硬件(毕竟这是Java)。

假设这些假设是有效的(有点元假设没有错),在api中公开执行模式有什么价值?

看起来你应该能够声明一个,并且顺序/并行执行的选择应该在下面的层中自动处理,无论是通过库代码还是JVM本身作为运行时可用内核的函数,问题的大小等。Stream

当然,假设并行流也可以在单核机器上运行,也许总是使用并行流就可以实现这一目标。但这真的很丑陋 - 为什么在我的代码中有对并行流的显式引用,而它是默认选项?

即使有一种情况,你故意想要硬编码使用顺序流 - 为什么没有一个子接口用于此目的,而不是污染执行模式开关?SequentialStreamStream


答案 1

看起来你应该能够声明一个流,并且顺序/并行执行的选择应该在下面的层中自动处理,无论是通过库代码还是JVM本身作为运行时可用内核的函数,问题的大小等。

现实情况是,a)流是一个库,没有特殊的JVM魔力,b)你不能真正设计一个足够聪明的库,以自动弄清楚在这种特殊情况下正确的决定是什么。没有合理的方法来估计一个特定函数在不运行它的情况下会有多昂贵 - 即使你可以内省它的实现,你不能 - 现在你正在在每个流操作中引入一个基准测试,试图弄清楚并行化它是否值得并行度开销的成本。这是不切实际的,特别是考虑到您事先也不知道并行度开销有多糟糕。

由于性能提高,给定适当的内核数量和问题大小来证明开销合理,并行流始终是首选。

在实践中,并非总是如此。有些任务太小了,不值得并行化,而并行性总是有一些开销。(坦率地说,大多数程序员倾向于高估并行性的有用性,当它真正损害性能时,到处都打耳光。

基本上,这是一个足够困难的问题,你基本上必须把它推到程序员身上。


答案 2

这个问题中有一个有趣的案例表明,有时并行流可能在数量级上更慢。在该特定示例中,并行版本运行十分钟,而顺序版本运行几秒钟。


推荐