On static in Java

In C, scoping rules aside, the following are pretty much the same:

static int x[] = { /* ... */ };
int foo()
{
    /* do something with x */
}

and

int bar()
{
    static int x[] = { /* ... */ };
    /* do something with x */
}

The static array x will go into the .data section of the executable. When the OS loads the executable into memory, it will ensure that the values for x are set in the appropriate place (e.g. by mapping its disk page to the virtual address in the ELF headers). In the second case, x is given some alias to avoid symbol conflicts.

There seems to be no way to do the second version in Java. Here’s how I tried:

static int xyzzy()
{
    final int x[] = { /* ... */ };
    /* do something with x */
}

This doesn’t do what you might think it does. While x cannot be changed, it is the reference to an array; the array elements themselves can be changed at will. Thus javac is unlikely to do anything smart here.

Indeed, in the above case, javac will initialize x with stack pushes every time xyzzy() is called. I had a real method like this, and making x a static member variable gave me an easy 2x speedup.

2 Replies to “On static in Java”

  1. Any time I use java it inspires hate; unfortunately I probably use it more than anything else 🙂

    It saddens me somewhat that array initialization on the stack is so inefficient. It compiles to something like 4 bytecode ops per array element (but I didn’t actually try to see what the JIT does with it). Since I am just using the array as a read-only look up table, it would be nice to be able to hint that to the compiler somehow.

    C gives a little more flexibility in this regard, but some would argue that being able to declare function-scope variables static is a defect in the C spec. Anyway, using a static member variable isn’t a bad solution.

Comments are closed.