我只是好奇:这两个循环实现之间的速度和性能有区别吗?假设size()方法返回处理一组元素的数组、集合或对象的长度(实际上它来自XOM api)。
实施1:
int size = someArray.size();
for (int i = 0; i < size; i++) {
// do stuff here
}
实施2:
for (int i = 0; i < someArray.size(); i++) {
// do stuff here
}
我只是好奇:这两个循环实现之间的速度和性能有区别吗?假设size()方法返回处理一组元素的数组、集合或对象的长度(实际上它来自XOM api)。
实施1:
int size = someArray.size();
for (int i = 0; i < size; i++) {
// do stuff here
}
实施2:
for (int i = 0; i < someArray.size(); i++) {
// do stuff here
}
从性能上看,差别不大。这是因为可以优化循环,以便内联 size() 查找,从而产生非常小的性能差异。
主要区别在于循环时大小是否发生变化。第一种情况将尝试迭代固定次数。在第二种情况下,迭代次数将取决于最终的 size()。
第一个片段的执行速度一定会更快,因为它只调用size()
一次。第二个片段调用size()
N 次。取决于实现。它可能会造成重大处罚,尤其是。如果编译器发现很难内联该方法和/或该size()
方法不只是返回非易失性变量等。
我会像这样重写它for(int i=0, s=someCollection.size(); i<s; i++)
注意:数组没有size()
方法。
是,有一点不同。在第一个循环中,size() 方法只被调用一次。在第二个中,它在每次迭代时被调用。
如果迭代修改了集合的大小(这非常罕见),则需要第二个。在大多数情况下,您应该更喜欢第一个,但要限制 size 变量的范围:
for (int i = 0, size = someArray.size(); i < size; i++) {
// ...
}
但大多数时候,你应该更喜欢 foreach 语法:
for (Foo foo : collection) {
// ...
}
这将有效地迭代数组或集合,即使对于 LinkedList,例如索引访问不是最佳的。
不用担心,现在 JVM 优化非常激进。
使用第二种形式,因为它更具可读性,而且很可能同样快。过早优化yada yada。
当您确实需要提高速度时,请始终先配置文件,不要猜测。
在局部变量中缓存 size() 不太可能使您的应用程序显着受益。如果是这样,您必须对庞大的数据集进行简单的操作。在这种情况下,您根本不应该使用 ArrayList。
也许值得注意的是这个结构:
for (String s : getStringsList()) {
//...
}
只调用getStringsList()
一次,然后在幕后对迭代器进行操作。因此执行冗长的操作或更改内部的某些状态是安全的getStringsList()
。
始终避免任何可以在循环之外完成的事情,例如方法调用、为变量赋值或测试条件。
方法调用比没有调用的等效代码成本更高,并且通过一次又一次地重复方法调用,您只会增加应用程序的开销。
将任何方法调用移出循环,即使这需要重写代码。
好处 :-
除非编译器对其进行优化,否则将为循环中的每次迭代计算循环条件。
如果条件值不会改变,如果方法调用移出循环,代码将执行得更快。
笔记 :-
If the method returns a value that will not change during the loop, then store its value in a temporary variable before the loop.
Hence its value is stored in a temporary variable size outside the loop, and then used as the loop termination condition.