Nellieder
Nellieder

Reputation: 13

access array through array huge performance loss

lets look at the following two java methods:

static void performance1() {
    int a=0; 
    int b=0;
    int[] arrayA = { 3, 4, 5 };
    int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000000; i++) {
        for (int k = 0; k < 100; k++) {
            a = arrayA[2];
            b = arrayB[1];
        }
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);

}

static void performance2() {
    int a=0; 
    int b=0;
    int[] arrayA = { 3, 4, 5 };
    int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000000; i++) {
        for (int k = 0; k < 100; k++) {
            b = arrayB[arrayA[2]];
        }
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);

}

The first method takes 209 ms to execute on my system, the seccond 4295! so 20 times as much. How can this be? As far as i can see this i can get a 20time performance increase if i declare 3 seperate variables instead of arrayA, because the following method executes very fast again:

static void performance3() {
    int a=0; 
    int b=0;
    int[] arrayA = { 3, 4, 5 };
    int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000000; i++) {
        for (int k = 0; k < 100; k++) {
            b = arrayB[a];
        }
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);

}

Am i overlooking something obvious here? it really seems suprising to me that the difference is so huge. Thank you anyways for explanations:)

Upvotes: 1

Views: 59

Answers (2)

FredK
FredK

Reputation: 4084

In the first code, a is always set to 5 and b to 5, regardless of what your loop indices are, so the compiler has eliminated the loops entirely, so it really ends up something like:

int a=0; 
int b=0;
int[] arrayA = { 3, 4, 5 };
int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
long start = System.currentTimeMillis();
a = 5;
b = 5;
long end = System.currentTimeMillis();
System.out.println(end - start);

Upvotes: 1

ninja.coder
ninja.coder

Reputation: 9648

When you do b = arrayB[1]; it directly references the value stored at location 1 but when you do b = arrayB[arrayA[2]]; it has to first retrieve the value arrayA[2] and then retrieve the value of arrayB[] based on the value retrieve in the earlier step.

The compiler is smart enough to optimize the activity in first step but not in the second step.

It will be more clear if you look the the byte code generated by these two methods.

Upvotes: 1

Related Questions