public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
根据Android documentation,在上面的代码中,零更慢。但我不明白为什么?好吧,我还没有那么深入,但据我所知length
是一个字段而不是方法。所以当循环检索它的值时,它与从局部变量检索的不同之处是什么?一旦初始化,数组长度总是固定的。我错过了什么?
答案 0 :(得分:8)
我想这是因为在zero
,他总是需要从mArray
和one
中检索信息,他可以访问它。这意味着,zero
需要两个“方法”:
但one
只需要一个“方法”:
答案 1 :(得分:3)
在第一个示例中,JVM需要首先获取对数组的引用,然后访问其长度字段。
在第二个例子中,它只访问一个局部变量。
在桌面JVM上,这通常是优化的,这两种方法是等效的,但似乎Android的JVM没有这样做......但是......
答案 2 :(得分:2)
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
这里,如果你看一下for循环,每次迭代计算的数组长度就会降低 表现。
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
在这种情况下,长度在循环之前计算,然后在循环中使用。
答案 3 :(得分:2)
这是一个范围问题。访问实例变量比方法变量慢,因为它不存储在相同的内存位置。 (因为可能更频繁地访问方法变量)。
同样适用于len,但需要额外的优化。无法从方法外部更改len
,编译器可以看到它永远不会更改。因此,它的值更可预测,循环可以进一步优化。