Java - for循环终止表达式之间的区别

时间:2011-02-26 10:24:32

标签: java loops performance xom

我只是好奇:这两个循环实现之间的速度和性能是否存在差异?假设 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
}

6 个答案:

答案 0 :(得分:3)

从性能的角度来看,差别不大。这是因为可以优化循环,以便内联size()查找,从而导致性能差异很小。

主要区别在于循环时大小是否发生变化。第一种情况将尝试迭代固定次数。在第二种情况下,迭代次数取决于最终大小()。

答案 1 :(得分:1)

第一个代码段必须执行得更快,因为它只调用size()一次。第二个片段呼叫size() N次。取决于impl。它可能会造成重大的惩罚,尤其是如果编译器发现难以内联该方法和/或size()方法不仅仅返回非易失性变量等。

我已经像for(int i=0, s=someCollection.size(); i<s; i++)

那样重写了它

注意:数组没有size()方法。

答案 2 :(得分:1)

是的,有区别。在第一个循环中,size()方法只调用一次。在第二个中,它在每次迭代时调用。

如果迭代修改了集合的大小(这是非常罕见的),则需要第二个。在大多数情况下,您应该更喜欢第一个,但是限制size变量的范围:

for (int i = 0, size = someArray.size(); i < size; i++) {
    // ...
}

但是大多数时候,你应该更喜欢foreach语法:

for (Foo foo : collection) {
    // ...
}

将有效地迭代数组或集合,即使对于LinkedList,例如,索引访问不是最佳的。

答案 3 :(得分:1)

不要担心,最近JVM优化非常激进。

使用第二种形式,因为它更具可读性,而且最有可能。过早优化yada yada。

当你确实需要提高速度时,请先进行剖析,不要猜测。

在本地变量中缓存size()极不可能显着地使您的应用受益。如果是这样,您必须对庞大的数据集进行简单的操作。在这种情况下,你根本不应该使用ArrayList。

答案 4 :(得分:0)

也许值得注意的是这个结构:

for (String s : getStringsList()) {
    //...
}

仅调用getStringsList()一次,然后在后台操作迭代器。因此,在getStringsList()内执行冗长的操作或更改某些状态是安全的。

答案 5 :(得分:0)

始终避免在循环之外可以执行的任何操作,如方法调用,为变量赋值或测试条件。

方法调用比没有调用的等效代码更昂贵,并且通过一次又一次地重复方法调用,您只需为应用程序增加开销。

将所有方法调用移出循环,即使这需要重写代码。

好处: -

除非编译器对其进行优化,否则将为循环中的每次迭代计算循环条件。

如果条件值不会改变,如果将方法调用移出循环,代码将执行得更快。

注意: -

如果方法返回一个在循环期间不会改变的值,则在循环之前将其值存储在临时变量中。

因此,它的值存储在循环外部的临时变量大小中,然后用作循环终止条件。