因此,我一直在研究并行运行的流,并根据API文档和我阅读的其他支持材料来监视流的行为。
我创建了两个并行流,并运行distinct()
,其中一个对流进行排序,而另一个对它进行无序处理。然后,我使用forEachOrdered()
打印结果(以确保在运行distinct之后确保看到的是流的结果遇到顺序),并且可以清楚地看到无序版本不会保持原始顺序,但是对于大型数据集,显然会增强并行性性能。
有API注释建议,当流无序时,limit()
和skip()
操作也应更有效地并行运行,因为不必检索第一个n
元素,您就可以获取任何n
元素。我试图以与上述相同的方式对此进行模拟,但是当与有序和无序流并行运行时,结果始终是相同的。换句话说,当我打印出运行极限之后的结果时,即使对于无序(并行)流,它仍然始终是前n个元素的选择?
谁能解释一下?我尝试改变输入数据集的大小和n的值,但没有区别。我会以为它将捕获任何n个元素并针对并行性能进行优化?有没有人实际看到这种情况在实践中发生,并且可能提供一种始终如一地展示这种行为的解决方案?
最佳答案
您可能试图从SIZED / SUBSIZED源(例如arrayList.stream()
,Arrays.stream(array)
,IntStream.range()
等)创建流,并立即发出limit
或skip
操作。这种情况在limit
/ skip
实现中进行了特别优化(请参阅SliceOps),并且对于有序和无序流都以相同的速度运行(并且实际上运行非常快)。如果删除此类特征(例如,添加过滤步骤),您将看到在此之后使流无序确实很有帮助。像这样编写测试:
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(..)...
或者,您可以使用非SUBSIZED源进行测试(例如
TreeSet
或HashSet
)。