栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

当.stream()。parallel()做同一件事时,为什么存在Collection.parallelStream()?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

当.stream()。parallel()做同一件事时,为什么存在Collection.parallelStream()?

的Javadoc

Collection.(parallelS|s)tream()
Stream
本身不回答这个问题,所以它的关闭为理由的邮件列表。我浏览了lambda-
libs-spec-
observers档案,找到了一个专门关于Collection.parallelStream()的线程,另一个发现了java.util.Arrays是否应该提供parallelStream()进行匹配(或者实际上是否应该匹配)的线程。删除)。没有一劳永逸的结论,所以也许我错过了另一个清单中的某些内容,或者此事在私人讨论中解决了。

参与者的观点很清楚,因此,答案基本上只是相关引语的组织,并在 [方括号]中做 了一些说明,并按重要性顺序排列(据我解释)。

parallelStream()涵盖了一个非常常见的情况

Brian Goetz在第一个线程中,解释了为什么

Collections.parallelStream()
即使删除了其他并行流工厂方法之后,仍然有价值的原因:

对于每个 [stream factory] ,我们都 没有
明确的并行版本;我们最初是这样做的,为了减少API的表面积,我们将其削减的理论是,从API中删除20种以上的方法值得在表面的皱纹和性能成本之间进行权衡。但是我们没有使用Collection做出选择。
__

.intRange(...).parallel()

我们可以删除

Collection.parallelStream()
,也可以添加所有生成器的并行版本,或者什么也不做,将其保留不变。我认为所有这些在API设计方面都是合理的。

尽管有点不一致,但我还是很喜欢现状。不是使用2N个流构建方法,而是使用N +
1个,但是额外的1个覆盖了很多情况,因为它是每个Collection都继承的。因此,我可以为自己辩解,为什么拥有额外的1方法是值得的,为什么接受不再进行的不一致是可以接受的。

别人不同意吗?N + 1 [仅适用Collections.parallelStream()] 是这里的实际选择吗?还是我们应该追求N的纯度
[依靠Stream.parallel()] ?还是2N (所有工厂的并行版本) 的便利性和一致性?还是有一些更好的N + 3
[Collections.parallelStream()加上其他特殊情况] ,对于某些我们要特别支持的特殊选择情况?

Brian Goetz在后面有关以下内容的讨论中坚持这一立场

Arrays.parallelStream()

我还是很喜欢Collection.parallelStream; 它具有巨大的可发现性优势,并且在API表面积方面提供了相当大的回报-
一种新的方法,但是在很多地方都提供了价值,因为Collection是流源的真正常见情况。

parallelStream()性能更高

布莱恩·格茨(Brian
Goetz):

直接版本 [parallelStream()]
的性能更高,因为它需要更少的包装(要将流转换成并行流,您必须先创建顺序流,然后将其状态的所有权转移到新的Stream中。)

为了回应KevinBourrillion对效果是否显着的怀疑,Brian再次:

取决于您计数的认真程度。道格在进行并行操作的过程中会计算单个对象的创建和虚拟调用,因为在开始分叉之前,您就处在阿姆达尔定律的错误一侧–这是发生在可以分叉任何工作之前的“序列分数”这将您的盈亏平衡点进一步推高。因此,快速获取并行操作的设置路径很有价值。

道格·李(Doug Lea)跟进,但对冲了他的位置:

处理并行库支持的人们需要对这种事情进行一些态度上的调整。在即将成为典型机器的计算机上,您浪费的每个周期设置并行性的成本为64个周期。如果它需要创建64个对象来启动并行计算,您可能会有不同的反应。

就是说,只要API不排除有效的实现,我总是完全支持强迫实现者为更好的API而更加努力。因此,如果杀戮

parallelStream
真的很重要,我们将找到某种方法来使
stream().parallel()
位翻转或类似现象。

确实,以后的讨论

Arrays.parallelStream()

注意到了更低的Stream.parallel()成本。

stream()。parallel()有状态使未来复杂化

在讨论时,可以将流从顺序切换到并行再切换回去可以与其他流操作交错进行。 Brian Goetz代表Doug
Lea解释了为什么顺序/并行模式切换可能会使Java平台的未来开发变得复杂:

我将竭尽全力解释原因:因为您也不喜欢它(例如有状态方法(排序,不同,限制)),这使我们越来越无法使用传统数据来表达流管道并行构造,这进一步限制了我们将它们直接映射到明天的计算基质的能力,无论是矢量处理器,FPGA,GPU还是我们自己准备的任何东西。

Filter-map-reduce可以非常清晰地映射到各种并行计算基板上;过滤器并行映射顺序排序限制极限并行映射uniq减少没有。

因此,这里的整个API设计在简化表达用户可能想要表达的内容与以一种可以通过透明成本模型快速预测的方式进行表达之间存在许多张力。

此模式切换在进一步讨论后被删除。在该库的当前版本中,流管道是顺序的或并行的。最后一次致电

sequential()
/
parallel()
获胜。除了回避状态问题之外,此更改还提高了
parallel()
用于从顺序流工厂建立并行管道的性能。

将parallelStream()公开为一等公民可以提高程序员对库的认识,从而使他们编写更好的代码

Brian Goetz再次回应了Tim
Peierls的论点,该论点

Stream.parallel()
允许程序员在并行化之前顺序地理解流:

对于这种顺序直觉的价值,我的看法略有不同。我认为普遍的“顺序期望”是整个努力中最大的挑战之一。人们 不断
带来不正确的顺序偏差,这导致他们做一些愚蠢的事情,例如使用单元素数组来“欺骗”“愚蠢”的编译器以使其捕获可变的局部变量,或者使用lambda作为映射参数将会在计算过程中使用的一种突变状态(以一种非线程安全的方式),然后,当它指出他们正在做什么时,耸耸肩说:“是的,但是我没有这样做在平行下。”

我们进行了很多设计折衷,以合并顺序流和并行流。我相信这样做的结果是干净的,并且会增加该库在10年以上仍然有用的机会,但是我并不特别喜欢鼓励人们认为这是一个连续的库,上面钉着一些平行的书包的想法。在一边。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/414023.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号