Does Sun's HotSpot JIT compiler automatically apply "final" to Java local variables?
Asked Answered
S

1

7

I've heard that this is the case, but I couldn't find a definitive online source to confirm it.

Background: A colleague likes to make his local variables final. One of his reasons for doing so is performance. My contention is that Java's HotSpot Just In Time compiler will automatically detect invariant local variables, and make them final, so there is no performance benefit to doing that ourselves.

Note that I'm not asking whether it's good coding practice to make local variables final, because there are already plenty of (off-topic) SO questions about that.

EDIT: mrhobo makes a good point about optimization of the bytecode for integer literals. I should have given an example of the type of code I was talking about, with my question:

Object doSomething(Foo foo) {
    if (foo == null) {
        return null;
    }

    final Bar bar = foo.getBar();
    final Baz baz = this.bazMap.get(bar);

    return new MyObject(bar, baz);
}

Do you think the same type of optimization happens in this scenario, because bar and baz are both marked final? Or does HotSpot automatically detect that they're not changing within the scope of the method, and treat them as final anyway?

Similar Questions

Serpasil answered 7/3, 2014 at 16:54 Comment(7)
"A colleague likes to make his local variables final. One of his reasons for doing so is performance." => that is not going to improve performance. So the rest of the discussion is unnecessary! It is a different story for fields: a final field is not the same as a non-final field.Meredithmeredithe
@Meredithmeredithe "that is not going to improve performance." ==> reference?Serpasil
The fact that the bytecode is the same (as pointed out in one of the links you posted) is one strong hint. But if you think about it, final fields have very specific semantics in the Java Memory Model which makes them different from non-final fields, possibly affecting performance. However a local variable is a local variable - I fail to imagine how making it final could influence performance.Meredithmeredithe
I can see the bytecode changing from iload to iconst when changing effectively final local ints variables to final..Minda
@mrhobo iconst generally refers to a literal. So if you write final int i = 1; you will have an iconst corresponding to 1. If you write int i = 1; you will get the same.Meredithmeredithe
If you need a citation, see Java Platform Performance Strategies and Tactics, written by two of the folks who worked on Sun's hotspot optimizers. (Claimer: I'm related to one of the authors.)Slaver
You may want to read up on SSA to understand why final on local variables in Java (const in C++ is a different topic, since local variables can change their value if passed somewhere) is completely uninteresting from the compilers POV for optimizations.Guanajuato
G
7

To understand why final for local variables is completely uninteresting for the compiler, some background at how compilers work will be helpful. Basically no compiler operates on the source code (or bytecode) itself, instead they parse it into some kind of intermediate representation (often several different ones while applying optimizations). And pretty much every compiler I know of uses some form of static-single assignment or short SSA form for its intermediate representation.

As the name says SSA form basically means that every variable is assigned a value only once. To make this clearer, assume we have the following simple code fragment:

y = 4
x = 5
y = 6
z = x + y

In SSA form this looks something like the following then:

y_1 = 4
x_1 = 5
y_2 = 6
z_1 = y_2 + x_1

So why do we do this? Because it makes many compiler optimizations a whole lot easier (it is for example trivial to see that the first write to y can be eliminated since we never read it). So if you want you may see this as every variable already being final for the compiler.

PS: loops and branches do make this a bit more complicated, but I don't want to sidetrack the discussion too much there - the wiki article has a short explanation on how to solve those problems though.

Guanajuato answered 11/3, 2014 at 0:30 Comment(2)
Thanks @Voo. Does the Java compiler use SSA form for Objects, as well as literals like ints?Serpasil
@Steve SSA form works with variables not the objects themselves, that's an important difference. So yes it does, there's no real difference between a variable pointing to an object and a variable containing a primitive here.Guanajuato

© 2022 - 2024 — McMap. All rights reserved.