Home > Enterprise >  Why does the Java Compiler not inline these calls in a single if clause?
Why does the Java Compiler not inline these calls in a single if clause?

Time:01-18

I have been pulled into a performance investigation of a code that is similar to the below:

private void someMethod(String id) {
   boolean isHidden = someList.contains(id);
   boolean isDisabled = this.checkIfDisabled(id);

   if (isHidden && isDisabled) {
     // Do something here
   }
}

When I started investigating it, I was hoping that the compiled version would look like this:

private void someMethod(String id) {
   if (someList.contains(id) && this.checkIfDisabled(id)) {
     // Do something here
   }
}

However, to my surprise, the compiled version looks exactly like the first one, with the local variables, which causes the method in isDisabled to always be called, and that's where the performance problem is in.

My solution was to inline it myself, so the method now short circuits at isHidden, but it left me wondering: Why isn't the Java Compiler smart enough in this case to inline these calls for me? Does it really need to have the local variables in place?

Thank you :)

CodePudding user response:

First: the java compiler (javac) does almost no optimizations, that job is almost entirely done by the JVM itself at runtime.

Second: optimizations like that can only be done when there is no observable difference in behaviour of the optimized code vs. the un-optimized code.

Since we don't know (and the compiler/runtime presumably also doesn't know) if checkIfDisabled has any observable side-effects, it has to assume that it might. Therefore even when the return value of that method is known to not be needed, the call to the method can't be optimized away.

If the body (or bodies, due to polymorphism) of the checkIfDisabled method is simple enough then it's quite possible that the runtime can actually optimize away that code, if it recognizes that the calls never have a side-effect (but I don't know if any JVM actually does this specific kind of optimization).

But that optimization is only possible at a point where there is definite information about what checkIfDisabled does. And due to the dynamic class-loading nature of Java that basically means it's almost never during compile time.

CodePudding user response:

Java compiler optimizations are tricky. Most optimizations are done at runtime by the JIT compiler. There are several levels of optimizations, the maximum number of optimizations by default will be made after 5000 method invocations. But it is rather problematic to see which optimizations are applied, since JIT compile the code directly into the platform's native code

  • Related