Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do java finals help the compiler create more efficient bytecode? [duplicate]

Possible Duplicate:
Does use of final keyword in Java improve the performance?

The final modifier has different consequences in java depending on what you apply it to. What I'm wondering is if additionally it might help the compiler create more efficient bytecode. I suppose the question goes deep into how the JVM work and might be JVM specific.

So, in your expertise, do any of the following help the compiler, or do you only use them for the normal java reasons?

  • Final classes
  • Final methods
  • Final fields
  • Final method arguments

Thanks!

EDIT: Thanks for all your answers! Please note that, as @Zohaib suggested, my question is a duplicate of this. I didn't search well enough before posting. I'm not deleting it because you guys made good contributions, but the answers could be merged. I'll let the "vote for close" system decide unless told otherwise.

like image 789
Miquel Avatar asked Dec 02 '11 09:12

Miquel


People also ask

Does final in Java improve performance?

Making a class, method, or variable final in Java helps to improve performance because JVM gets an opportunity to make assumptions and optimization.

When should I use final in Java?

You use the final keyword in a method declaration to indicate that the method cannot be overridden by subclasses. The Object class does this—a number of its methods are final .

Does Java compiler optimize code?

The JVMs JIT compiler is one of the fascinating mechanisms on the Java platform. It optimizes your code for performance, without giving away its readability. Not only that, beyond the “static” optimization methods of inlining, it also makes decisions based on the way that the code performs in practice.

Which compiler improves the performance of Java?

The JIT compiler helps improve the performance of Java programs by compiling bytecodes into native machine code at run time. The JIT compiler is enabled by default.


2 Answers

The bytecodes are not significantly more or less efficient if you use final because Java bytecode compilers typically do little in the way optimization. The efficiency bonus (if any) will be in the native code produced by the JIT compiler1.

In theory, using the final provides a hint to the JIT compiler that should help it optimize. In practice, recent HotSpot JIT compilers can do a better job by ignoring your hints. For instance, a modern JIT compiler typically performs a global analysis to find out if a given method call is a call to a leaf method in the context of the application's currently loaded classes. This analysis is more accurate than your final hints can be, and the runtime can even detect when a new class is loaded that invalidates the analysis ... and redo the analysis and native code generation for the affected code.

There are other semantic consequences for use of final:

  • Declaring a variable as final stops you from accidentally changing it. (And expresses your intention to the reader.)
  • Declaring a method as final prevents overriding in a subclass.
  • Declaring a class as final prevents subclassing entirely.
  • Declaring a field as final stops a subclass from changing it.
  • Declaring a field as final has important consequences for thread-safety; see JLS 17.5.

In the right circumstances, these can all be good. However, it is clear that they limit your options for reuse by creating subclasses. This needs to be considered when deciding whether or not to use final.

So good practice is to use final to (broadly speaking) express your design intentions, and to achieve other semantic effects that you require. If you use final solely as an optimization hint, you won't achieve much.


There are a couple of exceptions where final could lead to small performance improvements on some platforms.

  • Under certain circumstances, declaring a field as final changes the way that the bytecode compiler deals with it. I've given one example above. Another is the "constant variable" case (JLS 4.12.4) where a static final field's value will be inlined by the bytecode compiler both in the current classes, and in other classes, and this may affect the observed behavior of code. (For example, referring to a constant variable will NOT trigger class initialization. Hence, the addition of a final may change the order of class initialization.)

  • It is conceivable that declaring a field or local parameter as final may allow minor JIT compiler optimization that wouldn't otherwise be done. However, any field that can be declared as final could also be inferred to be effectively final by the JIT compiler. (It is just not clear that the JIT compiler actually does this, and whether that affects the generated native code.)

However the bottom line remains the same. You should use final to express your design intentions, not as an optimization hint.


1 - This answer assumes that we are talking about a recent JVM with a good JIT or AOT compiler. 1) The earliest Sun Java implementations didn't have a JIT compiler at all. 2) Early Android Java implementations had compilers which did a poor job of optimizing. Indeed the early Android developer documentation advised various source-level micro-optimizations to compensate. This advice has since been removed.

like image 132
Stephen C Avatar answered Sep 20 '22 21:09

Stephen C


That question has already been asked quite a lot and the answer generally is: the compiler might do some optimisations (e.g. inline constants which are final static fields) but generally you shouldn't bother with this, since those performance gains might actually not be noticable. Just use the final keyword for the "normal" Java reasons (make fields or parameters immutable, prevent subclassing or overriding of methods).

like image 42
Thomas Avatar answered Sep 22 '22 21:09

Thomas