为此,我和我的 friend 发生了争执。 考虑以下代码段,
for(i=0; i<someList.size(); i++) {
//some logic
}
此处 someList.size()
将在每次迭代时执行,因此建议将此大小计算迁移到循环外(之前)。
现在当我像这样使用扩展的 for 循环时会发生什么,
for(SpecialBean bean: someBean.getSpecialList()) {
//some logic
}
是否有必要将someBean.getSpecialList()
移到循环外?
如果我按原样保留第二个代码段,someBean.getSpecialList()
会执行多少次?
最佳答案
重复调用 list.size()
不会导致任何性能损失。 JIT 编译器很可能会内联它,即使没有内联它,它仍然非常便宜,因为它只涉及读取字段的值。
第一个示例的一个更严重的问题是循环体必须涉及 list.get(i)
并且对于 LinkedList
,访问 i th 元素具有 O(i) 成本,由于指针追踪,它具有相当重要的常数因子,这转化为 CPU 级别上的数据相关负载。 CPU 的预取器无法优化此访问模式。
这意味着当应用于 LinkedList
时,总体计算复杂度将为 O(n2)。
您的第二个示例通过 Iterator
编译为迭代,并将仅评估一次 someBean.getSpecialList().iterator()
。 iterator.next()
的成本在所有情况下都是恒定的。
关于java - 增强的 for 循环性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12155987/