性能提示问题

时间:2013-08-13 10:04:20

标签: java android

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是一个字段而不是方法。所以当循环检索它的值时,它与从局部变量检索的不同之处是什么?一旦初始化,数组长度总是固定的。我错过了什么?

4 个答案:

答案 0 :(得分:8)

我想这是因为在zero,他总是需要从mArrayone中检索信息,他可以访问它。这意味着,zero需要两个“方法”:

  1. 访问mArray
  2. 访问mArray.length
  3. one只需要一个“方法”:

    1. 访问len

答案 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,编译器可以看到它永远不会更改。因此,它的值更可预测,循环可以进一步优化。