skip() 在并行流上是否存在好的用例?

Does a good use case exist for skip() on parallel streams?


编辑于 2015 年 9 月


当我最初在 2015 年 2 月问这个问题时, 中报告的行为是违反直觉的,尽管 规范允许(尽管有些文档中的小不一致)。

然而,, where I think he clearly demonstrated that the behaviour reported in this question was actually a bug. , and admitted that it was a bug to not stop the back-propagation of the UNORDERED characteristic of the Stream on skip(), when triggered by a terminal operation that wasn't forced to respect the encounter order of the elements (such as forEach()). Furthermore, in the comments of his own answer, he shared a link to the posted issue in JDK's bug tracking system.

问题的状态现在已解决,其修复版本为 9,这意味着该修复将在 JDK9 中可用。但是,它也被反向移植到 JDK8 更新 60,构建 22

所以从 JDK8u60-b22 开始,这个问题就没有意义了,因为现在 skip() 根据直觉行事,即使在并行流上也是如此。


我原来的问题如下...


最近和一些同事讨论过这个问题。我说在并行流上使用 skip() 是毫无用处的,因为似乎没有很好的用例。他们告诉我有关性能提升、FJ 池处理、jvm 可用内核数等的信息,但是他们无法给我任何有关其用法的实际示例。

skip() 在并行流上是否存在好的用例?

参见 。请阅读问题和答案以及评论,因为那里有很多好的论据。

顺序与并行的选择只是执行策略之一。存在并行选项,因此,如果问题的具体情况(问题大小、流操作的选择、每个元素的计算工作、可用处理器、内存带宽等)允许,则可以通过并行获得性能优势。并非这些细节的所有组合都会带来性能优势(有些甚至可能会受到惩罚),因此我们让用户单独指定执行策略中的操作。

对于像skip()limit()这样的操作,本质上与遇到顺序相关,确实很难提取大量并行性,但这是可能的;这通常发生在每个元素的计算工作量(通常称为 'Q')非常高时。

这种情况可能很少见(这可能是你的意思);这并没有使操作和执行模式的组合 "useless",只是用途有限。但是,人们并没有根据人们可以想象的有用的组合来设计具有多个维度(操作,执行模式)的API;假设每个组合都有一个合理的语义(在这种情况下它确实如此),最好允许所有模式下的所有操作并让用户决定哪个对他们有用。