tags:

views:

316

answers:

5

I'm writing for Android (Java).

I'm declaring int's and float's as part of an ongoing loop.

Some of them don't need to be changed after declaration.

If I set them all to final when declaring, will things run quicker?

[Edit]

Thanks everyone. I didn't actually expect it to make any improvements, I just noticed, after browsing the source of various large projects, it was fairly common. Cheers

A: 

I'd consider it a good practice to make variables final (you might use Eclipse's Preferences > Java > Code Style > Clean Up to do so). While performance might actually improve, I'd expect the differences to be negligible. In my opinion, it helps with readability of code though (i.e. no need to look for assignments) which certainly is a Good Thing (tm).

sfussenegger
Care to explain why the performance might improve? Are there some optimizations that rely on the "final" attribute? The final attribute can be checked for violations at compile-time, so I'd be surprised if the compiler can't do those optimizations anyway....
aioobe
The compiler might optimize within a tight scope, but "final" is a good definitive hint on that. But as the compiler or VM is best considered as a black box, there is no reason not to give it a hint, let alone assume it does some optimizations.
Eiko
Since it can decide compile-time if it's valid to put "final" in front of a variable or not, it could *try* to put final in front of each variables and do those optimizations anyway if it's legal, right?
aioobe
Since public static and public instance variables can't be safely assumed to be final the compiler won't ever be able to assume they are. If you bring reflection to the mix, no instance or static variable can. But I said it 'might' improve. As I consider a potential performance difference negligible, I don't really care whether it does or not. I like the improvement in readability which is more important to me.
sfussenegger
@aioobe: that's one of the best argument I've seen from anyone.
polygenelubricants
Readability is subjective and there are varying opinions on readability and excessive usage of final.
Robin
@Robin agreed, it always is
sfussenegger
+1  A: 

Although setting to final might have impact on the speed, the answer will most probably be different for each VM or device.

Declaring them final, however, doesn't hurt, and one could even call it good programming style.

As for performance, this looks almost certainly like premature optimization. Profile, find bottlenecks, rethink your algorithms. Don't waste your time with "final" just because of performance - it will barely solve any problem.

Eiko
People like to tell it's best to ignore performance until problems occur. Regarding existing code, I totally agree. But often it won't hurt to do things right from the beginning without wasting any time optimizing.
sfussenegger
@sfussenegger that seems great in theory, but many times its also a horrible idea. The few projects I tried that on are unreadable and a nightmare to debug and maintain. I spend so much more time maintaining them than I saved doing the optimization the first time around.
Mike
+6  A: 

Things will not run quicker. The final keyword is just compile time syntactic sugar.


If it were actually static final, then you could take benefit of compiletime calculation and inlining of the value in any refernce. So, with for example:

private static final long ONE_WEEK_IN_MILLIS = 7 * 24 * 60 * 60 * 1000L;

public void foo(Date date) {
    if (date.getTiem() > System.currentTimeMillis() + ONE_WEEK_IN_MILLIS) {
        // No idea what to do here?
    }
}

the compiler will optimize one and other so that it ends up like:

private static final long ONE_WEEK_IN_MILLIS = 604800000L;

public void foo(Date date) {
    if (date.getTiem() > System.currentTimeMillis() + 604800000L) {
        // No idea what to do here?
    }
}

If you run a decompiler, you'll see it yourself.

BalusC
Reflection is my favorite API just for that. *`private final Field field;`, you say? ~reflection magic~ Not anymore!* Also I love Javassist for final classes for the same reason, there's nothing as fun as injecting new methods to `java.lang.*` classes :D
Esko
@BalusC: "Things will not run quicker." -- this is generally true, but there's SomeReallyFunkyStuff with Android's implementation of Java that may make this an exception. Somehow.
polygenelubricants
How would you override the final keyword? I just tried it but received `java.lang.IllegalAccessException: Can not set static final java.lang.String field Main$Foo.BAR to java.lang.String` thrown from a method called `throwFinalFieldIllegalAccessException`.
sfussenegger
@sfussenegger: `static final` (compiletime **constant**) is very different from `final`.
BalusC
ah, I think I remember. Final instance variables can be set using reflection. Access to them is often inlined though. As a result, `field.get(obj)` and `foo.field` return different results. Funky stuff :)
sfussenegger
But the question was about variables within a loop...
Eiko
@Eiko: that's correct. What's your point? Or was that a comment to sfussenegger? Variables inside a loop can indeed never be `static final`. In the future please use `@nickname` to make clear who you're talking to :)
BalusC
@BalusC: Sorry, it was pointed to your answer. In what way does it answer the question? It seems you talk about final fields while frinkz' question was about local variables within a loop - so declared within a for() or while() block.
Eiko
@Eiko: His question was about local **and final** variables in a loop, yes. I still don't see your point though. Final fields or final local variables, doesn't matter. The keyword is still compiletime syntactic sugar and doesn't matter in performance.
BalusC
@BalusC: How would reflection work for a variable declared within a loop? I am not a VM / compiler expert, but I guess it's up to the compiler what to make out of the code in that loop, and its optimizations might depend on the use of the final keyword. Recognizing that the value never changes is not hard, but probably not a requirement to ship a compiler. I wholeheartedly agree that it won't speed things up, encourage to use it anyway for other reasons. But it can be a hint to the compiler and is unrelated to reflection.
Eiko
@Eiko: Oh, I now see your confusion. With reflection I was indeed talking about `final` as instance variable, not as local variable. I'll clarify one and other.
BalusC
@BalusC Great, thanks :)
Eiko
+1  A: 

If you also make it static (a class variable) it can increase performance, and it is also good programming practice to use final for variables that you know will not change. Though, you may not want it to be a class variable, in which case, I am not sure if can improves performance, but I think it may in many cases.

http://docs.sun.com/app/docs/doc/819-3681/6n5srlhjs?a=view

The dynamic compiler can perform some constant folding optimizations easily, when you declare constants as static final variables.

Declare method arguments final if they are not modified in the method. In general, declare all variables final if they are not modified after being initialized or set to some value.

So for example, if you have code that multiples two of your final variables, during run-time the VM may use what would normally be sleep/downtime to calculate the result of that multiplication so it doesn't have to do it in the busy periods.

BobTurbo
Note: `static final` (compiletime **constants**) is very different from `final`.
BalusC
Yeah, I edited my post :) But there is no inherent problem if loops are using static final variables.
BobTurbo
`final` variables can also be declared in method scope (I understand that the OP is talking about that). They cannot be `static final`.
BalusC
oh yeah, I see, he is declaring them in a loop. Well, I think it will still increase performance in many situations if final is used. I added another quote on the same page. I guess that the VM may find an appropriate time to perform the constant folding optimisations even during run-time.
BobTurbo
final on local variables (including parameters) only exists at compile time. It does not exist in the class file so cannot aid in anyway at runtime.
Robin
I can't find anything in the documentation that suggests final on local variables or parameters is tracked, but those are optimisation suggestions on Sun's own website.. so.
BobTurbo
A: 

When we declare any variable final, means at compilation time it would be identified and while running the application JVM does not check it for any manipulation as it is declared as final(constant). so definately we are removind overhead from JVM.

so we could say it will improve performance, if depends on your case is the variable is constant make it final better if you make if static final.....

they are optimized by JVM are kept in the Constant Pool with the Classfile "http://negev.wordpress.com/java-memory-brief/"

Rozer
JVM does not check during runtime. Have you ever got a `RuntimeException` about that?
BalusC
it means , JVM won't contain the value of that final field as any non final field, they are optimized by JVM are kept in the Constant Pool with the Classfile "http://negev.wordpress.com/java-memory-brief/"
Rozer