Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance tips questions

Tags:

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;
    }
}

According to Android documentation, in above code, zero is slower. But I don't understand why ? well I haven't learn that much deep but as I know length is a field not method. So when loop retrieves its value, how its different from retrieving from local variable ? and array length is always fixed once initialized. What am I missing ?

like image 286
xmen Avatar asked Aug 13 '13 10:08

xmen


4 Answers

Well I guess this is because at zero, he always needs to retrieve the information from mArray and in one, he has it accessible. This means, zero needs two "methods":

  1. Access mArray
  2. Access mArray.length

But one only needs one "methods":

  1. Access len
like image 191
MalaKa Avatar answered Sep 28 '22 17:09

MalaKa


In the first example, the JVM needs to first fetch the reference to the array and then access its length field.

In the second example, it only accesses one local variable.

On desktop JVMs this is generally optimised and the two methods are equivalent but it seems that Android's JVM does not do it... yet...

like image 23
assylias Avatar answered Sep 28 '22 17:09

assylias


It is a matter of scope. Accessing an instance variable is slower than a method variable because it is not stored in the same memory places. (because method variables are likely to be accessed more often).

Same goes for len, but with an extra optimization. len cannot be changed from outside the method, and the compiler can see that it will never change. Therefore, its value is more predictable and the loop can be further optimized.

like image 35
njzk2 Avatar answered Sep 28 '22 16:09

njzk2


  public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

Here if you look at the for loop array length is calculated for every iteration, that degrades the performance.

  public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

In this case the length is calculated before for loop and then used in the loop.

like image 42
Ritesh Gune Avatar answered Sep 28 '22 15:09

Ritesh Gune