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

时间:2015-02-14 23:19:48

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


于2015年9月编辑


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

然而,Tagir Valeev asked a new question on June, 2015,我认为他清楚地证明了这个问题中报告的行为实际上是一个错误Brain Goetz answered his question,并承认这是一个错误,以阻止UNORDERED Stream skip()特征的反向传播,当时forEach()由终端操作触发,该操作未被强制遵守元素的遭遇顺序(例如skip())。此外,在他自己的回答评论中,他分享了link to the posted issue in JDK's bug tracking system

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

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


我原来的问题是......


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

并行流上的{{1}}是否存在一个好的用例?

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

1 个答案:

答案 0 :(得分:5)

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

对于skip()limit()之类的操作,它们与遭遇顺序有着内在的联系,实际上很难提取很多并行性,但它是可能的;这通常发生在每个元素的计算工作(通常称为Q')非常高的情况下。

这种情况可能很少见(这可能是你的意思);这并没有使操作和执行模式的组合“无用”,而仅仅是有限的用途。但是,根据人们可以想象的组合,人们不会设计具有多个维度(操作,执行模式)的API;假设每个组合都有一个合理的语义(在这种情况下它会这样做),最好允许所有模式中的所有操作,并让用户决定哪个对它们有用。