限制和跳过操作在无序时变得无状态

Do limit and skip operations become stateless when unordered

我的问题很简单。 java 流上的中间限制和跳过操作被标记为有状态操作 - 我假设是因为它们默认需要限制或跳过有序流上的前 n 个元素。

如果我通过调用 unordered() 方法或使用无序源使输入源流无序,我们是否可以有效地说这些操作可以被认为是无状态的,或者我在这里遗漏了什么?

我假设您的问题是关于当前 Stream 中的并行流 API 实现顺序流不以任何方式使用排序。

当前并行无序 skip/limit 实现对每个并行任务使用大小为 128 的缓冲区,因此您可能会从源中读取比实际需要更多的元素。这样做是为了减少对共享原子变量的可能争用,这可能对低 Q 任务(每个元素处理速度非常快的任务)至关重要。所以要回答你的问题,不,无序的 skip/limit 操作仍然是有状态的。

您可以使用以下程序轻松检查:

AtomicLong counter = new AtomicLong();
IntStream.range(0, 1_000_000).parallel().unordered().filter(x -> true)
        .peek(x -> counter.incrementAndGet()).limit(1000).toArray();
System.out.println(counter.get());

它打印实际从源中获取了多少元素。在我的四核系统上,此代码通常打印 1280 (128*10) 或 1408 (128*11),即使请求了 1000 个元素。

不,limitskip 仍然是有状态操作,因为元素的处理取决于有关其他元素处理的信息(即它们是否已被处理)。

这些操作对于无序流更容易实现,但这不会改变它们的状态性质。

你可以通过简单地问自己来判断:“这个操作是否可以通过只看元素而不是其他任何东西(除了在开始整个流操作之前已知的不变信息)来实现?”