2017-05-29 27 views
0

OCP书中说,所有的流都默认排序,但可以使用unordered()方法将有序流转换为无序流。这会使一个更快的并行流?

它也表示,在调用parallel()终端操作之前,将此方法用作中间操作时,此方法可以大大提高性能。我的问题是:下面的parallelstream会比那个下面的更快吗?

Arrays.asList(1,2,3,4,5,6).stream().unordered().parallel() 

Arrays.asList(1,2,3,4,5,6).parallelStream(). 

PS:我知道一个parallelstream doesent提高性能的小集合工作时,但让我们假装我们是一个非常大的集合在这里工作。

第二个流仍然是正确的?那么第一个会有更好的表现吗?

谢谢

回答

3

您声明默认情况下所有流都是有序的:情况并非如此。例如,如果您的源是HashSet,则不会订购生成的流。

关于将并行流无序化为“大大提高性能”的问题:与往常一样,在性能方面,它取决于(在终端操作,中间操作,流的大小等)

The java.util.stream package javadoc给出了一些三分球是回答你的问题,至少在一部分:

对于并行流,放松排序约束有时可以实现更高效的执行。如果元素的排序不相关,某些集合操作(​​如过滤重复项(distinct())或分组减少项(Collectors.groupingBy()))可以更有效地实施。类似地,与内部命令相关的操作(如limit())可能需要缓冲以确保正确的排序,从而破坏并行性的好处。在流有碰到命令的情况下,但用户并不特别关心该碰到命令,明确地用unordered()对流排序可能会改善某些有状态或终端操作的并行性能。然而,即使在排序约束下,大多数流管线(例如上面的“块的权重总和”)仍然有效地并行化。

+1

此外,有关遭遇顺序的更多信息:http://www.lambdafaq.org/in-what-order-do-the-elements-of-a-stream-become-available/他们还得出结论:可能的表现改进取决于你之后对流的操作。 –

+0

@Malte Hartwig:当然,这取决于后续的操作,a)如果他们还没有排在第一位,b)是否有办法从无序中受益。在当前的Java 8参考实现中,我找不到任何* .unordered()链接的例子。 (不要混淆使用'findAny()'而不是'findFirst()'等,这些*有*效果)... – Holger

0

对于此处显示的情况,绝对不是。这里的元素太少了。一般来说,你应该测量,然后得出结论,但这个几乎是一件容易的事情。

而且阅读:Parallel Processing

事情有关unordered执行终端操作,流管道就不能不提秩序 - 这意味着额外的成本。如果没有维护的顺序,则流更快。

请注意,一旦您拨打unordered,就无法将订单取回。你可以排序,但这可能不意味着最初的订单。

同样适用于findFirst例如findAny并行处理。

+0

“太多元素”是什么意思? –

+0

@MalteHartwig编辑... – Eugene

相关问题