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

2022-09-03 09:54:40

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

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

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


答案 1

这不仅“为每个循环编写基准测试是不可行的”,而且适得其反。特定的、特定于应用程序的循环在放入微基准测试时可能执行完全不同的操作。

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

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


答案 2

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

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

除此之外,只需确保在进行基准测试时使用JMH即可。


推荐