【问题标题】:Java stream limit and skip behaviour when unordered and parallel无序和并行时的 Java 流限制和跳过行为
【发布时间】:2016-04-29 00:16:33
【问题描述】:

所以我一直在尝试并行运行流,并根据我阅读的 API 文档和其他支持材料监控它们的行为。

我创建了两个并行流并运行distinct(),一个流是有序的,一个是无序的。然后我使用forEachOrdered() 打印结果(以确保在 distinct 运行后看到流的结果遇到顺序),并且可以清楚地看到无序版本不保持原始顺序,但使用大型数据集,显然会提高并行性能。

有 API 说明建议 limit()skip() 操作也应该在流无序时更有效地并行运行,因为您可以获取任何 n 而不必检索第一个 n 元素元素。我尝试以与上述相同的方式对此进行模拟,但是当与有序流和无序流并行运行时,结果总是相同的。换句话说,当我在运行限制后打印出结果时,即使对于无序(并行)流,它仍然总是为前 n 个元素选择?

谁能解释一下?我尝试改变输入数据集的大小和 n 的值,但没有任何区别。我会认为它会抓取任何 n 个元素并针对并行性能进行优化?有没有人在实践中真正看到过这种情况,并且可能提供一个始终如一地展示这种行为的解决方案?

【问题讨论】:

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


    【解决方案1】:

    您可能尝试从 SIZED/SUBSIZED 源(如arrayList.stream()Arrays.stream(array)IntStream.range() 等)创建流并立即发出limitskip 操作。这种情况在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 源(例如,TreeSetHashSet)进行测试。

    【讨论】:

      猜你喜欢
      • 2016-05-07
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      相关资源
      最近更新 更多