Use stack variables whenever possible
Editor’s note: The following articles are excerpts from the book "Practical Java" published by Addison-Wesley. You can order this book from Borders.com.
When frequently accessing variables, you need to consider from where they are accessed. Is the variable static , on the stack, or an instance variable of a class? Where you store a variable has a significant impact on the performance of code that accesses it. For example, consider the following code:
|
Each method in this code executes the same loop for the same number of iterations. They differ only in that each loop increments a different type of variable. The method stackAccess increments a local stack variable, instanceAccess increments a class instance variable, and staticAccess increments a class static variable.
instanceAccess and staticAccess take about the same amount of time to execute. stackAccess , however, is two to three times faster. Accessing a stack variable is so much faster because the JVM performs less work than when accessing static or class instance variables. Look at the generated bytecode for the three methods:
|
Looking at the bytecode reveals why stack variables are more efficient. The JVM is a stack-based machine and therefore is optimized to access and manipulate stack data. All local variables are stored in a local variable table and manipulated on the Java operand stack and can be accessed very efficiently. Accessing static and instance variables is more costly because the JVM must use a more expensive opcode and access them from the constant pool. (The constant pool holds symbolic references to all types, fields, and methods used by a type.)
Typically, after the first access of a static or instance variable from the constant pool, the bytecode is dynamically changed by the JVM to use a more efficient opcode. Regardless of this optimization, stack variables are still faster to access.
Given these facts, the previous code can be restructured to operate more efficiently by accessing stack variables instead of instance or static variables. Consider the modified code:
|
The methods instanceAccess and staticAccess are modified to copy their instance or static variables to a local stack variable. When manipulation of a variable is complete, the value is copied back to the instance or static variable. This simple change significantly improves the performance of instanceAccess and staticAccess . The execution times of the three methods are now effectively equal, with instanceAccess and staticAccess executing only about 4 percent slower than stackAccess .
This does not mean you should avoid using static or instance variables. You should use whatever storage mechanism makes sense for your design. For example, if you access static or instance variables in a loop, you can significantly improve the performance of the code by temporarily storing them in a local stack variable. This provides a more efficient sequence of bytecode instructions for the JVM to execute.
If you found this post useful you may also want to check these out:
- Use Synchronized or Volatile when Accessing Shared Variables
- Do Not Reassign the Object Reference of a Locked Object
- The Whys and Why Nots of Java Accessors
- If I Were King: A Proposal for Fixing the Java Programming Language’s Threading Problems
- Reflection: A New Way to Discover Information about Java classes
- Java and SNA: A case study
