Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Compiler optimizations

Can you count on compilers to optimize your Java code?

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Developers are accustomed to compilers from languages other than Java that support various optimizations. In development, code is typically compiled with optimizations turned off so that source-level debuggers can operate on nonoptimized code. Once code has been thoroughly debugged, compiler options are enabled to produce code that executes as fast and efficient as possible. This model is used because most 3GLs (third-generation languages) are advanced enough to provide stable and predictable optimizations that exploit existing software and hardware platforms.

Because current compiler technology is so reliable, some developers have depended on the compilers' optimization features to clean up sloppily developed code. Some compilers can hide coding inefficiencies, but none can hide poorly designed code. For example, the following code sample shows an array being initialized:


int a = 5; int b = 7; int *acc[10];
for (i=0; I<10;i++) *acc[i] = a + b;


Because a and b are invariant and do not change inside of the loop, their addition doesn't need to be performed for each loop iteration. Almost any good compiler optimizes the code. An optimizer moves the addition of a and b outside the loop, thus creating a more efficient loop. For example, the optimized code could look like the following:

int     a = 5;
        int b = 7;
        int     c = a + b;

int *acc[10];
for (i=0; I<10;i++) *acc[i] = c;


This is a common and simple example of invariant code optimization. Obviously, optimizations can be a lot more complex. That most Java compilers do little when it comes to optimizing code may be surprising. Some of the more common optimizations supported across Java compilers are constant folding and dead code elimination.

Constant folding

Constant folding refers to the compiler precalculating constant expressions. For example, examine the following code:


static final int length = 25; static final int width = 10; int res = length * width;


Execution time is not used to multiply those values; instead, multiplication is done at compile time. The code for the following variable assignment is modified to produce bytecode that represents the product of width and length:

        int res  = 250;



Dead code elimination

Simple dead code elimination prevents the compiler from generating bytecode for blocks that don't get executed. Dead code elimination does not affect the code's runtime execution. It does, however, reduce the size of the generated classfile. For example, the two expressions in method nocode() are not converted to bytecode:

class Text
{
        public static final boolean trace = false;
        public void nocode()
        {
            if (Test.trace)
            {
                  <....>
            }

if (false) { <....> } } }
Code is still generated if an expression evaluates to false at runtime. The only time bytecode is not produced is when the expression evaluates to false at compile time.

Summary

Developers should realize that only a few optimizations are supported by most Java compilers. For those who use compilers that do not perform a lot of optimizations, three options may be considered:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources