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

dav*_*wil 18 java parallel-processing java-8 java-stream

来自Stream javadoc:

流管道可以顺序执行或并行执行.此执行模式是流的属性.通过初始选择的顺序或并行执行来创建流.

我的假设:

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

假设这些假设是有效的(对于一些元假设没有错误),在api中暴露执行模式的价值是什么?

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

当然,假设并行流也可以在单个核心机器上运行,也许只是总是使用并行流来实现这一点.但这真的很难看 - 为什么我的代码中的并行流显式引用它是默认选项?

即使存在您故意想要对顺序流进行硬编码的情况 - 为什么不仅仅是SequentialStream为此目的的子接口,而不是Stream使用执行模式切换进行污染?

Lou*_*man 26

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

现实情况是,a)流是一个库,并没有特殊的JVM魔法,并且b)你无法真正设计一个足够智能的库来自动确定在这种特殊情况下正确的决定是什么.没有明智的方法来估计一个特定功能在没有运行的情况下会花费多少 - 即使你可以反省它的实现,你也不能 - 现在你要在每个流操作中引入一个基准测试,试图弄清楚如果并行化将是值得并行开销的成本.这是不切实际的,特别是考虑到你事先并不知道并行性开销有多糟糕.

由于性能的提高,在给定适当数量的内核和问题大小以证明开销合理的情况下,并行流总是更可取的.

在实践中并非总是如此.有些任务非常小,以至于它们不值得并行化,并行性总是会产生一些开销.(坦率地说,大多数程序员倾向于高估并行性的有用性,在它真正损害性能时将其打到各处.)

基本上,这是一个很难的问题,你基本上不得不把它推到程序员身上.


Tag*_*eev 5

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