Java Local VS Instance Variable Access Speed

Java local vs instance variable access speed

Ok, I've written a micro-benchmark (as suggested by @Joni & @MattBall) and here are the results for 1 x 1000000000 accesses for each a local and an instance variable:

Average time for instance variable access: 5.08E-4
Average time for local variable access: 4.96E-4

For 10 x 1000000000 accesses each:

Average time for instance variable access:4.723E-4
Average time for local variable access:4.631E-4

For 100 x 1000000000 accesses each:

Average time for instance variable access: 5.050300000000002E-4
Average time for local variable access: 5.002400000000001E-4

So it seems that local variable accesses are indeed faster that instance var accesses (even if both point to the same object).

Note: I didn't want to find this out, because of something I wanted to optimize, it was just pure interest.

P.S. Here is the code for the micro-benchmark:

public class AccessBenchmark {
private final long N = 1000000000;
private static final int M = 1;

private LocalClass instanceVar;

private class LocalClass {
public void someFunc() {}
}

public double testInstanceVar() {
// System.out.println("Running instance variable benchmark:");
instanceVar = new LocalClass();

long start = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
instanceVar.someFunc();
}

long elapsed = System.currentTimeMillis() - start;

double avg = (elapsed * 1000.0) / N;

// System.out.println("elapsed time = " + elapsed + "ms");
// System.out.println(avg + " microseconds per execution");

return avg;
}

public double testLocalVar() {
// System.out.println("Running local variable benchmark:");
instanceVar = new LocalClass();
LocalClass localVar = instanceVar;

long start = System.currentTimeMillis();
for (int i = 0 ; i < N; i++) {
localVar.someFunc();
}

long elapsed = System.currentTimeMillis() - start;

double avg = (elapsed * 1000.0) / N;

// System.out.println("elapsed time = " + elapsed + "ms");
// System.out.println(avg + " microseconds per execution");

return avg;
}

public static void main(String[] args) {
AccessBenchmark bench;

double[] avgInstance = new double[M];
double[] avgLocal = new double[M];

for (int i = 0; i < M; i++) {
bench = new AccessBenchmark();

avgInstance[i] = bench.testInstanceVar();
avgLocal[i] = bench.testLocalVar();

System.gc();
}

double sumInstance = 0.0;
for (double d : avgInstance) sumInstance += d;
System.out.println("Average time for instance variable access: " + sumInstance / M);

double sumLocal = 0.0;
for (double d : avgLocal) sumLocal += d;
System.out.println("Average time for local variable access: " + sumLocal / M);
}
}

Java Optimization: Local Variable Vs Instance Variable

I wrote a little test program with jdk1.6, below

Results:

* 594ms for dostuff (which creates a local)

* 58ms for dostuff2 (which uses the instance)

public class Test {

static long counter=0;
public static void main(String[] args) {
long t1 = System.nanoTime();
Test test = new Test();
for (int i=0;i<1000000000;i++) {
test.doStuff();//or dostuff2
}
long t2 = System.nanoTime();
System.err.println((t2-t1)/1000000);
System.err.println(counter); // to check it wasnt optimised away
}

private void doStuff() {
List l = new ArrayList();
if (l!=null) {
counter++;
}
}

List l2 = new ArrayList();
private void doStuff2() {
if (l2!=null) {
counter++;
}
}
}

As a result, it seems that the instance is faster than using a local, as one would expect.

However it seems you save about 0.5s per billion items, on my PC at least, so you'd need to really really need the perf gain to justify it

Why static/member variable are slower than local variable?

youre a victim of runtime optimization :-)

if you change your code a little:

Question q = new Question();
for (int i=0; i<2; i++) {
q.executeGlobal();
q.executeStatic();
q.executeLocal();
}

you get this:

Type Global: 38331943 ns
Type Static: 57761889 ns
Type Local: 3010189 ns
Type Global: 46249688 ns
Type Static: 52745009 ns
Type Local: 0 ns

what happens is that pretty soon the runtime realizes that your local variable keeps getting assigned, but never gets read (or used), and optimizes out the whole loop.

as for the difference between class instance fields and static fields, theyre both on the heap, but the static fields are shared across all object instances, so there's an extra level of indirection

Is it faster to access final local variables than class variables in Java?

The final keyword is a red herring here.
The performance difference comes because they are saying two different things.

public void forEach(IntIntProcedure p) {
final boolean[] used = this.used;
for (int i = 0; i < used.length; i++) {
...
}
}

is saying, "fetch a boolean array, and for each element of that array do something."

Without final boolean[] used, the function is saying "while the index is less than the length of the current value of the used field of the current object, fetch the current value of the used field of the current object and do something with the element at index i."

The JIT might have a much easier time proving loop bound invariants to eliminate excess bound checks and so on because it can much more easily determine what would cause the value of used to change. Even ignoring multiple threads, if p.apply could change the value of used then the JIT can't eliminate bounds checks or do other useful optimizations.

Use local variable vs access instance variable

Do whatever is more readable.

Usually the shorter code is easier to read, comprehend, and show correct, but if an expression becomes long and the itermediate expressions make sense on their own, then introduce a local variable to make the code clearer.

As far as performance goes, you don't know that there will be any performance hit one way or the other unless you profile the code. Optimization in Java happens at compile but also at runtime with modern JIT compliation. Compilers can do inlining, common subexpression elimination and all kinds of algebraic transformations and strength reductions that I doubt that your example will show any performance impact one way or the other.

And unless an expression like this is executed a billion times or more in a loop, readability wins.

Why is local variable access faster than class member access in Python?

self.m += 1 means you have to look up a local variable called self and then find the attribute called m

Of course if you just have to look up a local variable, it will be faster without the extra step.

It can be useful to look at what is happening under the hood:

>>> import dis
>>> dis.dis(StressTestLocal.do_work)
18 0 LOAD_CONST 1 (0)
3 STORE_FAST 1 (m)

19 6 LOAD_FAST 1 (m)
9 LOAD_CONST 2 (1)
12 INPLACE_ADD
13 STORE_FAST 1 (m)

20 16 LOAD_FAST 1 (m)
19 LOAD_CONST 3 (2)
22 INPLACE_MULTIPLY
23 STORE_FAST 1 (m)
26 LOAD_CONST 0 (None)
29 RETURN_VALUE
>>> dis.dis(StressTestMember.do_work)
10 0 LOAD_FAST 0 (self)
3 DUP_TOP
4 LOAD_ATTR 0 (m)
7 LOAD_CONST 1 (1)
10 INPLACE_ADD
11 ROT_TWO
12 STORE_ATTR 0 (m)

11 15 LOAD_FAST 0 (self)
18 DUP_TOP
19 LOAD_ATTR 0 (m)
22 LOAD_CONST 2 (2)
25 INPLACE_MULTIPLY
26 ROT_TWO
27 STORE_ATTR 0 (m)
30 LOAD_CONST 0 (None)
33 RETURN_VALUE


Related Topics



Leave a reply



Submit