Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of using a local variable to hold a global one?

I had a look at the source code of the String.hashcode() method. This was the implementation in 6-b14, which has been changed already.

public int hashCode() {
        int h = hash;
        if (h == 0) {
            int off = offset;
            char val[] = value;
            int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
}

My question is about this line:

int len = count;

Where count is a global variable representing the amount of characters of the String.

Why is a local variable len used here for the loop condition and not the global variable itself? Because there is no manipulating of the variable, only reading. Is it just good practice to use a local variable if a global field is used for reading from or writing to it? If the answer is yes why for reading too?

like image 742
Steve Benett Avatar asked Jun 13 '14 14:06

Steve Benett


1 Answers

Poking around in the String class I've found a comment regarding that strange assignment to a local variable in the String.trim() method reading "avoid getfield opcode".

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */

    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

So the whole thing seems to be about performance, as Frank Olschewski pointed out.

In the Java bytecode an instance variable is actually referenced by object and name (using the GETFIELD instruction). Without optimization, the VM must do more work to access the variable.

A potential performance hit of the code, then, is that it uses the relatively expensive GETFIELD instruction on each pass through the loop. The local assignment in the method removes the need for a GETFIELD every time through the loop.

The JIT-optimizer might optimize the loop but it also might not, so the developers probably took the safe path enforcing it manually.

There's a separate question on Avoiding getfield opcode which has the details.

like image 176
MicSim Avatar answered Oct 18 '22 05:10

MicSim