在执行其他操作之前查找流大小
在我的程序中,我反复收集了 1 个 Java 8 流,以将一个对象集合减少到一个对象集合。在整个执行过程中,此集合的大小可能会有很大差异:从 3 个对象到数百个对象。
public void findInterestingFoo(Stream<Foo> foos) {
internalState.update(foos.collect(customCollector()));
}
在优化代码和搜索瓶颈的过程中,我使流在某些时候并行。这在当时是有效的,因为收藏品都相当大。后来,在更改了程序的其他部分和参数后,集合变得更小了。我意识到不使流并行更有效。这是有道理的:为4个对象在多个线程上分配工作的开销根本不值得。不过,对于数百个对象来说,这是值得的。
如果我只能使大流并行,那将非常方便:
public void findInterestingFoo(Stream<Foo> foos) {
if (isSmall(foos)) {
internalState.update(foos.collect(customCollector()));
} else {
internalState.update(foos.parallel().collect(customCollector()));
}
}
当然,当从数组、集合或手动创建流时,可以手动执行此操作。也就是说,我们知道流中有哪些元素,因此可以对其进行跟踪。然而,我有兴趣以通用的方式解决这个问题,以便无论将哪种流传递给,它都能得到适当和尽可能有效的处理。findInterestingFoo
像count()
这样的东西可能会有所帮助,除了它在我收集它之前终止了流。
我很清楚流被设计为没有固定大小,特别是:
- 可能是无限的。虽然集合的大小有限,但流不需要。短路操作(如 或 可以允许无限流的计算在有限的时间内完成)。—
java.util.stream
package descriptionlimit(n)
findFirst()
不过,我想知道在对流执行任何操作之前,是否有任何方法可以确定流中有多少个元素。流真的不知道它是从有限集合创建的吗?
__________
1 千次。在我的情况下,优化这一点导致总运行时间从大约1.5秒加速到0.5秒。