This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there any performance reason to declare method parameters final in Java?
Does use of final keyword in Java improve the performance?
So there's a class-level object variable that's allocated upon object creation and stays put for the lifetime of the object:
class MyClass
{
private Rect rc = new Rect();
//...
}
What do I gain be declaring it final? Same question for method-level variables.
it is all completely implementation specific.
main reason to use final is to ensure that variable value is not allowed to be change over time. it's a matter of you code logic and not optimization.
Declaring variables final does have benefits that come from immutability. If used properly your code can be more thread safe, provided the variable you're making final does not have internal state that could be changed unexpectedly and effect other threads.
See the other answers here too about JVM optimizations.
Final has one obvious use, where it makes the object/variable immutable, now can this feature help in performance gains?
Quoting: The Final Word On the final Keyword, the performance gain you get using final is:
A field doesn't need to be ever reloaded, since its value is
guaranteed never to change.
But I see a flaw in the above statement, the value won't be reloaded if it's set only once and final guarantees that it will never be reloaded again, but this does not mean using final directly helps you in performance gain, the performance gain we get here is due to the property that if we make sure we do not set the to something else, it will anyway, won't be reloaded.
So, you answer:
Although, it is implementation specific to the JVM and atleast in the HotSpot, you will get no performance gains from using final. Read more: Does use of final keyword in Java improve the performance?
IBM also says you won't get ant performance gain out of final.
This might not give you 100% answer. But i have a point which i know.
There is lot of optimization gained by the jvm when you declare variables as final.
I remember a good example where i have if-else conditions in my program and in the condition since i used final variable, complier has evaluted which part of if-else is valid and it stripped out the other lines and i have seen it with javap. I will get you that example soon.
It allows for some optimization via memoization. For example, if you have a Rectangle class with final height and final width, then your rectangle's area function only needs to compute it once, since it knows that height and width cannot change.
I doubt that final fields have a hughe impact on performance, unless you have shared object in multiple threads.
However declaring methods final or even classes will help the jit to determine wether a method can be overridden, or can't. If the jit is certain the method is no where overwritten he might remove the method lookup and use a direct jump (jump subroutine). Also Jits like to inline small final methods.
Besides the obvious compile-time protection from modifications (*) you do gain some form of optimized access to its value. The compiler may for example replace the references of primitive variables with literal values. The runtime can for example place copies of the its content in each thread's private memory space to avoid accessing main memory. It does depend on each JVM implementation.
For local variables you do again have gains, both at compile-time and at run-time, mostly in the form of thread-access optimizations. Bear in mind though, that you will only ever notice these gains in hot spots of your code, code that executes hundreds or thousands of times per second.
(*) final only protects from compile-time modifications after the introduction of Accessible Objects.
Related
I was reading the ArrayBlockingQueue implementation code another day by Doug Lea and noticed a lot of methods (public, default, and private) have the following references:
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
I have asked around to have a reasonable explanation but so far no satisfactory answers. I am not quite sure why we need to have such local variables in the first place? And what is the benefit(s) of coding this way?
Maybe I missed some important points in concurrent programming. Could you please help to shed some lights on this?
A very good reason for a method to set a local variable to the value of an accessible class or instance variable, or a value accessible through one of those, is to thereafter be independent of any modifications to that variable by other threads. With some caveats, this allows the method that needs to access that value more than once to perform a consistent computation reflecting the state of the host object at some specific point in time, even if that state has changed by the time the result is returned. This is likely what's happening in the code you have been studying.
It happened that I just came across this link which explained some of the main arguments of coding this way:[In ArrayBlockingQueue, why copy final member field into local final variable?. Please read it to understand more, instead, I am hoping of not getting more confused. I believe it helps you to look at this practice from another angle. It seems it at least met some of my curiosities around this coding style.
After going through all relevant threads on the coding practice of assigning a final class variable to a local copy, i.e. a final class variable is never accessed directly from within a method, instead it is always referenced by a local variable reference:
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
Typically you will find this code style in ArrayBlockingQueue and other concurrent classes
The following are my findings:
It is an idiomatic use, made popular by Doug Lea, the main author of
the core Java library on multithreading/concurrency classes
The main consideration of this coding practice (or rather a hack) is for a small
performance optimization back in Java 5 era
It is arguable if such a trick can have a performance gain; Some argued it is opposite
with modern compiler; Others believe it is not needed
So my takings are that we should not be encouraged to adopt this practice. Because in many applications you don’t need it. Clean code maybe more important than a small performance gain; let alone no one is 100% certain whether this (a performance gain) is the case anymore.
This question already has answers here:
Does use of final keyword in Java improve the performance?
(14 answers)
Closed 7 years ago.
Now, I recently ran into a recommendation that you should use the keyword final as wide as possible. This is good in order to prevent a programmer from shooting his own leg - that is, reassign the variable that should not be reassigned.
But, does it serve any other goal? That is, can JVM use information about the final variables in order to optimize the bytecode somehow, so it would ran faster (build a better pipelining or use it in a multithreaded environment)? Or is just a syntactic sugar that minimizes the possibility of errors during code development?
IBM states:
Like many myths about Java performance, the erroneous belief that declaring classes or methods as final results in better performance is widely held but rarely examined. The argument goes that declaring a method or class as final means that the compiler can inline method calls more aggressively, because it knows that at run time this is definitely the version of the method that's going to be called. But this is simply not true. Just because class X is compiled against final class Y doesn't mean that the same version of class Y will be loaded at run time. So the compiler cannot inline such cross-class method calls safely, final or not. Only if a method is private can the compiler inline it freely, and in that case, the final keyword would be redundant.
As far as variables go, Java is smart enough to figure that a variable is not being changed anywhere in the method, and use this knowledge for optimization purposes. It does not need you to mark a variable final in order to know that.
Methods are a slightly different story: when you mark a method final, Java can invoke such method faster, because it no longer needs to check for its overrides. Still, hotspot is smart enough to figure out that there are no overrides, with or without the use of final.
Generally, though, this recommendation is intended to make your code easier to read and understand by others: making a variable final tells you readers that you are making a constant; making a class final tells your readers that the class is not designed for inheritance; making a method final tells your readers that the logic of that method should stay invariant across the inheritance hierarchy. In the long run, this information is more valuable than the potential to optimize your running code.
I think this recommendation is a bit too unspecific.
For example; I would recommend to avoid using final on classes and methods by default (because final classes break unit tests, respectively force you to use specific unit test frameworks to overcome final methods/classes).
I also find that using final for method parameters is just a waste of "screen space" (and thus: wasting "energy" on the side of the reader).
On the other hand, having only final attributes for classes can turn objects of such classes into immutable thingies; and that is a good thing.
As you see; there are many pros and cons on the usage of final; and I think that "readability" most often wins over "potential" performance improvements.
final methods may or may not be inlined by the JVM until they after they are loaded by the JVM. So, if you're sure the method is not going to be redefined, mark it as final.
Constants should always be static final since they will be immutable and jvm does not need to keep track of these variables since they will never change.
I have read that making something final and then using it in a loop will bring better performance, but is it good for everything? I have lots of places where there isnt a loop but I add final to the local variables. Does it make it slower or is it still good?
Also there are some places where I have a global variable final (e.g. android paint), does it mean I don't have to make it a local final when using it in loops?
The first thing you should consider is; What is the simplest and clearest way I can write this code. Often this performs well.
final local variables is unlikely to affect performance much. They can help clarity when you have long methods, but I would suggest breaking up method is a better approach.
final fields can affect performance to small degree, but a better reason to make it final is to make it clear that this field never changes (which also helps the JIT)
Don't think about performance. final on object member (fields) have significant memory semantics that may improve performance (but more importantly, its often necessary to make the code correctly work at all). You should always put final on object members whenever you can. For local variables however, you should only use it if it will improve code readerability, or can prevent bugs when a maintainer touches your code.
The general consensus of the Java community is that final on every local variables will make the code difficult to read. On the performance front, you can expect no optimization as local variables are easy to analyze for the compiler. In other words, the compiler can figure it out by itself.
From my experience most variables could be declared final.
However, it looks very ugly. That is my main point against it.
And if the part of the program is not performance critical, beware of premature optimization.
It's considered good form to use final where possible (for fields and variables, not classes and methods), if for no other reason than it makes testing easier. Final will never have a negative impact on performance.
Here are my 2 cents:
Use final on attributes to minimize mutability and for documentation purposes, only use final on local variables if they are used in inner/anonymous classes.
DON'T use it for microoptimizations! Especially don't use them on classes or methods because you think it will improve performance. Make classes and methods final to prohibit inheritance or overriding methods.
Final on attributes should not have any impact on performance. Except: in a multi threaded environment where several threads access the same field and "don't know" if they have to relaod it. Final on local variables has no impact at all, as nothing except the local scope can access them anyway.
Final on methods can have an impact during JIT compiling. If a method is final and small the compiler can inline it in loops, as it is clear that no one will have overwritten it.
I usually don't use final on attributes at all, as final attributes can not be loaded from DBs easily etc. Declaring pararameters to methods final lokos ugly (I never assign to them inside my code anyway) but might prevent simple bugs comming from typoes. However if you start using proper names for your variables you unliek make such typoes.
Theoretically, if you make a local variable final it can be optimized. I don't think making them final yourself really improves performance though, because the optimizer probably already detects when your locals don't change. That said, it can't hurt to help it a bit.
In some situations, it would help to change one variable into two, e.g. from this
String a = "foo";
if (lol) a += "bar";
for(.. 1000 ...) doSomething(a);
to
final String a;
{
String ma = "foo";
if (lol) ma += "bar";
a = ma;
}
for(.. 1000 ...) doSomething(a);
Disclaimer: I'm not a JIT expert.
Final variables are constants, therefore the compiler could generate constant value instead of variable referencing instruction. Of course that would improve speed (and commonly size as well).
Also there are some places where I have a global variable final (e.g. android paint), does it mean I don't have to make it a local final when using it in loops?
Sorry, do you mean you don't have to:
final int somefinalvalue = 0;
void amethod() {
final int somefinalvalue = 0; // repeated from global one
}
or what? remember that if you declare local variable which has the same name as global one, that would 'shadow' the global one. i.e. it's actually a totally different variable. if you already have the global one, just use that. no need to re-declare.
I don't think this should be your first concern, as mentioned by #perter-lawrey. First, compiler optimization can very much do the trick; second, there are some tools that can analyze your generated class files and do the same thing, for example, ProGuard: java shrinker, optimizer, obfuscator, and preverifier.
If I look at the java source source code in the OpenJDK or Hibernate or Apache I have yet to see any local variables declared final.
This suggests that the developers of some of the most widely used java software libraries:
do not believe the final keyword improves readablity.
do not believe it significantly improves performance.
Why do the majority of contrbuters on stackoverflow believe it it should be used (based on the highest voted responses)?
Probably because it's a hassle to type in the five LONG letters in the word final... why would they go through the pain of writing
final int x;
when it's twice as much typing as
int x;
?
We developers are lazy, you know... :P
do not believe the final keyword
improves readablity.
Some people (such as myself) find excessive finals decreases readability.
do not believe it significantly
improves performance.
final local variables does not improve performance.
As far as I'm aware, the final keyword has no impact on the runtime performance of your variables.
I believe it's primary purpose is to assist you in the catching of bugs. If you know something is never going to change, you mark it as such. Similar to why we use annotations where we can, any time we can trade a runtime bug for a compile time error, we do. Finding an error when you're working on it, and it's fresh in your mind, and it hasn't gone and corrupted someone's data causing you to lose customers, yeah that's a very good thing. You get the compile error, you fix it, you move on, you don't break the nightly build, yeah those are good things.
The final keyword has two uses:
declare a class or method as final in order to prevent subclassing/overrding
declare a variable as final in order to prevent changing it (assigning a new value)
Case 2 is normally applied to member variables in order to make the object immutable (at least partly) or to method parameters in order to prevent accidential assignments.
In case of a local variable (i.e. method scoped and not a parameter), that's normally not necessary or wanted, since those variables are likely to be changed within the method (otherwise you might not need them, except to cache a reference for method scope).
I doubt declaring a local variable final ever improves performance. By virtue of the existence of final, Java compilers are already required to be able to tell if a variable might be assigned more than once, or might not be initialized. Therefore, actually declaring a local as final doesn't tell the compiler anything it didn't already know--it's only for the benefit of the reader.
Now whether it sometimes improves readability, that's more subjective. In a complicated piece of code it can be nice to promise (to yourself, or to future readers) that a variable is only written once. But it might be nicer to simplify the code so that is readily apparent anyway.
DataflowAnomalyAnalysis: Found
'DD'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found
'DU'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DD and DU sound familiar...I want to say in things like testing and analysis relating to weakest pre and post conditions, but I don't remember the specifics.
NullAssignment: Assigning an Object to
null is a code smell. Consider
refactoring.
Wouldn't setting an object to null assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
MethodArgumentCouldBeFinal: Parameter
'param' is not assigned and could be
declared final
LocalVariableCouldBeFinal: Local
variable 'variable' could be declared
final
Are there any advantages to using final parameters and variables?
LooseCoupling: Avoid using
implementation types like
'LinkedList'; use the interface
instead
If I know that I specifically need a LinkedList, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
AvoidSynchronizedAtMethodLevel: Use
block level rather than method level
synchronization
What advantages does block-level synchronization have over method-level synchronization?
AvoidUsingShortType: Do not use the
short type
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
DD and DU anomalies (if I remember correctly—I use FindBugs and the messages are a little different) refer to assigning a value to a local variable that is never read, usually because it is reassigned another value before ever being read. A typical case would be initializing some variable with null when it is declared. Don't declare the variable until it's needed.
Assigning null to a local variable in order to "assist" the garbage collector is a myth. PMD is letting you know this is just counter-productive clutter.
Specifying final on a local variable should be very useful to an optimizer, but I don't have any concrete examples of current JITs taking advantage of this hint. I have found it useful in reasoning about the correctness of my own code.
Specifying interfaces in terms of… well, interfaces is a great design practice. You can easily change implementations of the collection without impacting the caller at all. That's what interfaces are all about.
I can't think of many cases where a caller would require a LinkedList, since it doesn't expose any API that isn't declared by some interface. If the client relies on that API, it's available through the correct interface.
Block level synchronization allows the critical section to be smaller, which allows as much work to be done concurrently as possible. Perhaps more importantly, it allows the use of a lock object that is privately controlled by the enclosing object. This way, you can guarantee that no deadlock can occur. Using the instance itself as a lock, anyone can synchronize on it incorrectly, causing deadlock.
Operands of type short are promoted to int in any operations. This rule is letting you know that this promotion is occurring, and you might as well use an int. However, using the short type can save memory, so if it is an instance member, I'd probably ignore that rule.
DataflowAnomalyAnalysis: Found
'DD'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found
'DU'-anomaly for variable 'variable'
(lines 'n1'-'n2').
No idea.
NullAssignment: Assigning an Object to
null is a code smell. Consider
refactoring.
Wouldn't setting an object to null assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
Objects in local methods are marked to be garbage collected once the method returns. Setting them to null won't do any difference.
Since it would make less experience developers what is that null assignment all about it may be considered a code smell.
MethodArgumentCouldBeFinal: Parameter
'param' is not assigned and could be
declared final
LocalVariableCouldBeFinal: Local
variable 'variable' could be declared
final
Are there any advantages to using final parameters and variables?
It make clearer that the value won't change during the lifecycle of the object.
Also, if by any chance someone try to assign a value, the compiler will prevent this coding error at compile type.
consider this:
public void businessRule( SomeImportantArgument important ) {
if( important.xyz() ){
doXyz();
}
// some fuzzy logic here
important = new NotSoImportant();
// add for/if's/while etc
if( important.abc() ){ // <-- bug
burnTheHouse();
}
}
Suppose that you're assigned to solve some mysterious bug that from time to time burns the house.
You know what wast the parameter used, what you don't understand is WHY the burnTHeHouse method is invoked if the conditions are not met ( according to your findings )
It make take you a while to findout that at some point in the middle, somone change the reference, and that you are using other object.
Using final help to prevent this kind of things.
LooseCoupling: Avoid using
implementation types like
'LinkedList'; use the interface
instead
If I know that I specifically need a LinkedList, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
There is no difference, in this case. I would think that since you are not using LinkedList specific functionality the suggestion is fair.
Today, LinkedList could make sense, but by using an interface you help your self ( or others ) to change it easily when it wont.
For small, personal projects this may not make sense at all, but since you're using an analyzer already, I guess you care about the code quality already.
Also, helps less experienced developer to create good habits. [ I'm not saying you're one but the analyzer does not know you ;) ]
AvoidSynchronizedAtMethodLevel: Use
block level rather than method level
synchronization
What advantages does block-level synchronization have over method-level synchronization?
The smaller the synchronized section the better. That's it.
Also, if you synchronize at the method level you'll block the whole object. When you synchronize at block level, you just synchronize that specific section, in some situations that's what you need.
AvoidUsingShortType: Do not use the
short type
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
I've never heard of this, and I agree with you :) I've never use short though.
My guess is that by not using it, you'll been helping your self to upgrade to int seamlessly.
Code smells are more oriented to code quality than performance optimizations. So the advice are given for less experienced programmers and to avoid pitfalls, than to improve program speed.
This way, you could save a lot of time and frustrations when trying to change the code to fit a better design.
If it the advise doesn't make sense, just ignore them, remember, you are the developer at charge, and the tool is just that a tool. If something goes wrong, you can't blame the tool, right?
Just a note on the final question.
Putting "final" on a variable results in it only be assignable once. This does not necessarily mean that it is easier to write, but it most certainly means that it is easier to read for a future maintainer.
Please consider these points:
any variable with a final can be immediately classified in "will not change value while watching".
by implication it means that if all variables which will not change are marked with final, then the variables NOT marked with final actually WILL change.
This means that you can see already when reading through the definition part which variables to look out for, as they may change value during the code, and the maintainer can spend his/her efforts better as the code is more readable.
Wouldn't setting an object to null
assist in garbage collection, if the
object is a local object (not used
outside of the method)? Or is that a
myth?
The only thing it does is make it possible for the object to be GCd before the method's end, which is rarely ever necessary.
Are there any advantages to using final parameters and variables?
It makes the code somewhat clearer since you don't have to worry about the value being changed somwhere when you analyze the code. More often then not you don't need or want to change a variable's value once it's set anyway.
If I know that I specifically need a
LinkedList, why would I not use one to
make my intentions explicitly clear to
future developers?
Can you think of any reason why you would specifically need a
LinkedList?
It's one thing to
return the class that's highest up the
class path that makes sense, but why
would I not declare my variables to be
of the strictest sense?
I don't care much about local variables or fields, but if you declare a method parameter of type LinkedList, I will hunt you down and hurt you, because it makes it impossible for me to use things like Arrays.asList() and Collections.emptyList().
What advantages does block-level synchronization have over method-level synchronization?
The biggest one is that it enables you to use a dedicated monitor object so that only those critical sections are mutually exclusive that need to be, rather than everything using the same monitor.
in the Java world, why should I not
use the type that best describes my
data?
Because types smaller than int are automtically promoted to int for all calculations and you have to cast down to assign anything to them. This leads to cluttered code and quite a lot of confustion (especially when autoboxing is involved).
AvoidUsingShortType: Do not use the short type
List item
short is 16 bit, 2's compliment in java
a short mathmatical operaion with anything in the Integer family outside of another short will require a runtime sign extension conversion to the larger size. operating against a floating point requires sign extension and a non-trivial conversion to IEEE-754.
can't find proof, but with a 32 bit or 64 bit register, you're no longer saving on 'processor instructions' at the bytecode level. You're parking a compact car in a a semi-trailer's parking spot as far as the processor register is concerned.
If your are optimizing your project at the byte code level, wow. just wow. ;P
I agree on the design side of ignoring this pmd warning, just weigh accurately describing your object with a 'short' versus the incurred performance conversions.
in my opinion, the incurred performance hits are miniscule on most machines. ignore the error.
What advantages does block-level
synchronization have over method-level
synchronization?
Synchronize a method is like do a synchronize(getClass()) block, and blocks all the class.
Maybe you don't want that