所以我一直在玩并行运行流,并根据API文档和我读过的其他支持材料监控它们的行为。
我创建了两个并行流并运行distinct()
,一个是流的顺序,一个是无序的。然后,我使用forEachOrdered()
打印结果(以确保在不同运行后我看到流的结果遇到顺序),并且可以清楚地看到无序版本不维护原始排序,但是使用大型数据集,显然会提高并行性能。
有一些API说明表明,当流无序时,limit()
和skip()
操作也应该更有效地并行运行,而不必检索第一个n
元素,可以获得任何n
个元素。我试图以与上面相同的方式模拟这个,但是当与有序和无序流并行运行时的结果总是相同的。换句话说,当我在运行限制后打印出结果时,即使对于无序(并行)流,它仍然总是选择前n个元素?
任何人都能解释一下吗?我尝试改变输入数据集的大小和n的值,它没有任何区别。我本以为它会抓住任何n个元素并优化并行性能?有没有人真正看到过这种情况在实践中发生,并且可能提供一种能够始终如一地展示这种行为的解决方案?
答案 0 :(得分:4)
您可能尝试从SIZED / SUBSIZED源创建流(例如arrayList.stream()
,Arrays.stream(array)
,IntStream.range()
等)并立即发出limit
或{{1操作。这种情况在skip
/ limit
实现中特别优化(参见SliceOps),并且对于有序和无序流以相同的速度运行(实际上运行速度非常快)。如果删除这些特征(例如,添加过滤步骤),您将看到在此之后使流无序有效。像这样写测试:
skip
或者,您可以使用非SUBSIZED来源进行测试(例如,input.stream().parallel().filter(x -> true).skip(..)...
input.stream().parallel().unordered().filter(x -> true).skip(..)...
input.stream().parallel().filter(x -> true).limit(..)...
input.stream().parallel().unordered().filter(x -> true).limit(..)...
或TreeSet
)。