Java 8流运行速度比for循环慢的关键指标?

在大多数情况下,Java 8流允许的代码比旧式for循环更具可读性。 但是,根据我自己的经验和我所读到的内容,使用流而不是for循环可能会导致性能损失(或偶尔会有改进),有时难以预测。

在一个大型项目中,为每个循环编写基准测试似乎不太可行,因此在决定是否用流替换for循环时,关键因素是什么 (例如,预期的集合大小,删除的值的预期百分比通过过滤,迭代操作的复杂性,减少或聚合的类型等,它们可能表明将导致的性能变化?

注意:这是我之前的问题的缩小,因为过于宽泛而关闭(并且并行流的方面在另一个SO问题中得到了很好的覆盖),所以让我们将其限制为顺序流。

它不仅“为每个循环编写基准测试都不可行”,而且反效果。 特定的,特定于应用程序的循环在被置于微基准测试中时可能完全不同。

对于实际应用,标准优化规则适用: 不要这样做 。 只需编写更具可读性的内容,并且只有在出现性能问题时,才能对整个应用程序进行概要分析以检查特定的循环或流是否真正成为瓶颈。 只有在这种情况下,您可以尝试在特定瓶颈的两个习语之间切换,看看它是否有所作为。

在大多数情况下,它不会。 如果存在真正的性能问题,它将源于操作类型,例如执行具有O(n²)时间复杂度的嵌套迭代等。此类问题不依赖于您是使用Stream还是for循环而是这两个习语之间的微小性能差异不会改变你的代码缩放的方式

streamsloops之间没有很大的一般速度差异,它们的优点/缺点是特定于问题的。 是否选择其中一个应该(主要)取决于代码的可读性。 对于某些性能比较,请参阅Benchmark1和Benchmark2 ,您可以在其中注意到Brian Goetz对其中一个答案的评论:

关于表现的结论虽然有效,却被夸大了。 在很多情况下,流代码比迭代代码更快,主要是因为流的每元素访问成本比使用普通迭代器更便宜。 在许多情况下,流版本内联到与手写版本相同的内容。 当然,魔鬼在于细节; 任何给定的代码都可能表现不同。

除此之外,请确保在您进行基准测试时使用JMH 。