Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a compliant Java compiler optimize this code?

I was teaching an introductory programming course today and was walking through some simple code involving variable assignments in Java. The point of the code wasn't to show off anything particular exciting, but mostly to make sure students understood variable assignment statements.

I had the following method up on the board and was tracing through it one line at a time:

private void simpleMethod() {
    int myInt = 137;
    myInt = 42;
    myInt = myInt + 1;

    /* ... code using myInt ... */
}

A student asked me whether myInt would ever actually hold the values 137 and 42 when the program ran, or if it would just jump straight to holding 43. I told the student that the code would execute each line in turn, so the variable would actually hold these intermediate values.

Honestly, though, I wasn't sure what bytecode javac would emit (completely ignoring the optimizations done by the JVM). Is javac (or any Java compiler) legally allowed to optimize the silly assignment statements away and to instead just directly initialize myInt to 43?

According to javap, on my system, the above code compiled with javac produces

   0: sipush        137
   3: istore_1      
   4: bipush        42
   6: istore_1      
   7: iload_1       
   8: iconst_1      
   9: iadd          
  10: istore_1      
  11: return        

So there is no optimization going on here. My question, though, is whether it's legal to optimize this or not, so this doesn't resolve anything.

like image 824
templatetypedef Avatar asked Jan 15 '13 06:01

templatetypedef


People also ask

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.

How do compilers optimize code?

Compiler optimization is generally implemented using a sequence of optimizing transformations, algorithms which take a program and transform it to produce a semantically equivalent output program that uses fewer resources or executes faster.

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.

How JIT works in Java?

The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it.


1 Answers

The JLS specifies only the contract of observable behavior that your program produces. Since myInt is local, the optimization can indeed be optimized at compile time, since this would produce a behavior consistent with the spec, and there's nothing in the spec that says it's not allowed (at least, not that I found!). Chapter 1 of the spec specifies the observable-ness of the spec explicitly: This document fully specifies the (apparent) order of evaluation of expressions.... Since the apparent behavior is unchanged by constant-folding to myInt = 43, the optimization would be consistent with the JLS.

In fact, the compilation target of a Java application isn't even specified in the JLS. Chapter 1 says that Java applications "normally" compile to the bytecode specified in the JVM spec (a separate document), but it does not require that they do so. There are some statements that must be optimized at compile time, but myInt is not one such. Even if myInt were a field, I think the optimization would be allowed; the different behavior would still be valid behavior, even if myInt is volatile (since it represents one valid ordering of events).

So, short answer, I think your student is correct; it's perfectly fine to optimize it to just myInt = 43. That said, javac generally does very little -- virtually nothing -- in the way of optimization. Optimizations are pretty much all done in the JIT.

like image 133
yshavit Avatar answered Nov 01 '22 14:11

yshavit