5

我只是好奇:这两个循环实现之间的速度和性能有区别吗?假设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
}
4

6 回答 6

4

从性能上看,差别不大。这是因为可以优化循环,以便内联 size() 查找,从而产生非常小的性能差异。

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

于 2011-02-26T10:41:11.290 回答
1

第一个片段的执行速度一定会更快,因为它只调用size()一次。第二个片段调用size()N 次。取决于实现。它可能会造成重大处罚,尤其是。如果编译器发现很难内联该方法和/或该size()方法不只是返回非易失性变量等。

我会像这样重写它for(int i=0, s=someCollection.size(); i<s; i++)

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

于 2011-02-26T10:28:43.990 回答
1

是,有一点不同。在第一个循环中,size() 方法只被调用一次。在第二个中,它在每次迭代时被调用。

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

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

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

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

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

于 2011-02-26T10:32:53.737 回答
1

不用担心,现在 JVM 优化非常激进。

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

当您确实需要提高速度时,请始终先配置文件,不要猜测。

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

于 2011-02-26T11:51:19.203 回答
0

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

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

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

于 2011-02-26T12:45:38.673 回答
0

始终避免任何可以在循环之外完成的事情,例如方法调用、为变量赋值或测试条件。

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

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

好处 :-

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

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

笔记 :-

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.

于 2015-04-06T05:46:00.447 回答