在性能 Lambda 或简单循环方面哪个会更好?

2022-08-31 22:29:29

我很快就阅读了Oracle Lambda Expression文档。

不过,这个例子帮助我更好地理解了:

//Old way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for(Integer n: list) {
System.out.println(n);
}

//New way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
list.forEach(n -> System.out.println(n));


//or we can use :: double colon operator in Java 8
list.forEach(System.out::println);

不过,我不明白为什么这是一项创新。它只是一个在“方法变量”结束时死亡的方法,对吧?为什么我应该使用这个而不是真正的方法?就性能而言,哪个是更好的选择。Lambda 或简单循环。


答案 1

我的建议是:

  1. 使用您和您的同事认为最易于维护的样式。

  2. 如果您和您的同事还对 lambdas 不满意,请继续学习。

  3. 不要痴迷于性能。它通常不是最重要的事情。

一般来说,lambda和流提供了一种更简洁,并且(一旦每个人都跟上速度)更易读的方式来表达这种算法。性能不是主要目标。

如果性能确实成为一个问题,那么标准建议是编码,测试,基准测试,分析和优化。并按照这个顺序去做!通过在编码阶段进行优化,或者通过优化对整体应用程序性能影响最小的代码,您可以轻松浪费大量时间。

  • 让应用程序基准测试告诉您是否需要优化。
  • 让探查器指出代码中值得优化的部分。

在此特定示例中,性能差异将太小而无法衡量。如果您扩展到数百万个元素的列表,则性能将主要由构建列表和写入数字所花费的时间主导。不同的迭代方式只会对整体性能做出一小部分贡献。


对于那些(尽管有上述所有情况)仍然想知道使用lambda还是传统循环更快的人来说,最好的一般答案是:

“这取决于各种因素,1)没有得到很好的理解,2)随着Java编译器技术的发展而变化。

我们可以为您提供具有特定Java主要/次要/补丁版本的特定示例的答案,但是概括是不明智的。


答案 2

为什么我应该使用这个而不是真正的方法?

你不应该。使用您更喜欢的方法。

至于性能,我想,所有这些版本的速度大致相同。此处的 I/O 操作 () 比调用 lambda 或创建迭代器的所有可能开销慢得多。通常可能会稍微快一些,因为它在单个方法中执行所有操作,而无需创建 and 调用 和(这是由 for-each 循环隐式完成的)。无论如何,这取决于许多因素,例如调用此代码的频率,列表的长度,JIT编译器是否设法使迭代器和/或lambda去虚拟化,等等。printlnforEachIteratorhasNextnext


推荐