derefed
derefed

Reputation: 689

Does the JVM optimize aliased variables?

I'm curious. If I make a few local variables that are used simply as aliases to other variables (that is, a new "alias" variable is simply assigned the value of some other variable and the alias' assignment never changes), does the JVM optimize this by using the original variables directly?

Say, for example, that I'm writing an (immutable) quaternion class (a quaternion is a vector with four values). I write a multiply() method that takes another Quaternion, multiplies the two, and returns the resulting Quaternion. To save on typing and increase readability, I make several aliases before performing the actual computation:

public class Quaternion {

    private double[] qValues;

    public Quaternion(double q0, double q1, double q2, double q3) {
        qValues = new double[] {q0, q1, q2, q3};
    }

    // ...snip...

    public Quaternion multiply(Quaternion other) {
        double a1 = qValues[0],
                 b1 = qValues[1],
                 c1 = qValues[2],
                 d1 = qValues[3],

                 a2 = other.qValues[0],
                 b2 = other.qValues[1],
                 c2 = other.qValues[2],
                 d2 = other.qValues[3];

        return new Quaternion(
                    a1*a2 - b1*b2 - c1*c2 - d1*d2,
                    a1*b2 + b1*a2 + c1*d2 - d1*c2,
                    a1*c2 - b1*d2 + c1*a2 + d1*b2,
                    a1*d2 + b1*c2 - c1*b2 + d1*a2
                );
    }

}

So, in this case, would the JVM do away with a1, b1, etc. and simply use qValues[n] and other.qValues[n] directly?

Upvotes: 2

Views: 387

Answers (4)

Alex
Alex

Reputation: 11090

As other answers have pointed out, there no concept of aliasing variables in Java, and the value of a variable is stored per variable declared.

Using local variables to store values of an array for future calculations is a better idea as it makes code more readable, and eliminates extra reads from an array.

That being said, creating local variables does increase the size of the allocated java stack frame in the thread for the method. This would not be an issue in this specific question, but greater number of local variables would increase the stack size required for execution. This would be especially relevant if recursion is involved.

Upvotes: 1

vanza
vanza

Reputation: 9903

The javac compiler won't do it. Disassembling a simple piece of code like this:

    int a = 1;
    int b = a;
    System.out.println("" + (a - b));

Shows:

   0: iconst_1      
   1: istore_1      
   2: iload_1       
   3: istore_2
   ...

But this is what the interpreter will be executing (and even the interpreter sometimes can do some basic optimization). The JIT compiler will handle these kinds of optimizations and many others; in the case of you method, it's even small enough to be inlined, so you don't even get the method call overhead once the JIT kicks in.

(e.g., in my example, the JIT can very easily do constant propagation and just do away with the variables and the calculation, just calling using "" + 0 as the argument to the println() method.)

But, at the end, just follow what JIT hackers always say: write your code to be maintainable. Don't worry about what the JIT will or will not do.

(Note: David is correct about variables not being "aliases", but copies of the original values.)

Upvotes: 1

David Harkness
David Harkness

Reputation: 36562

There is no such thing as an alias as you've described it in Java. When you assign a value from one memory location to a new variable, the JVM makes a copy of that value. If it were to create an alias, changing the underlying arrays during the calculation from another thread would alter the result. This does not happen in your example because you specifically told the JVM to make copies of the values first.

If you're worried about performance, don't be. Program correctness trumps all performance concerns. Any program that produces incorrect results faster is worthless. I'm not saying that accessing the arrays directly inside the calculation will necessarily produce incorrect results as I haven't seen the rest of the code, but I am saying that this type of micro-optimization is not worth your effort without first finding a performance problem and next performing timing tests to verify where that problem lies.

Upvotes: 2

Gelin Luo
Gelin Luo

Reputation: 14373

Your program should work but the answer to your questions is no. JVM will not treat a1 as an alias of qValues[0], instead it copy the value of the latter to the former.

Check this good referenece: http://www.yoda.arachsys.com/java/passing.html

Upvotes: -1

Related Questions