Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the Java compiler optimize an unnecessary ternary operator?

I’ve been reviewing code where some coders have been using redundant ternary operators “for readability.” Such as:

boolean val = (foo == bar && foo1 != bar) ? true : false; 

Obviously it would be better to just assign the statement’s result to the boolean variable, but does the compiler care?

like image 710
Bakna Avatar asked Feb 02 '19 18:02

Bakna


People also ask

Does the Java compiler optimize?

The compiler don't optimize the bytecode because it is optimized at run time by the JIT optimizer. If the type of runtime you are targeting don't have a JIT optimizer (even if it had a JIT compiler), or you are AOT compiling, I recommend using an optimizing obfuscator like Proguard or Allatori.

Are ternary operators faster in Java?

Moreover, as has been pointed out, at the byte code level there's really no difference between the ternary operator and if-then-else. As in the above example, the decision on which to choose is based wholly on readability.

Is ternary operator bad practice?

The conditional ternary operator can definitely be overused, and some find it quite unreadable. However, I find that it can be very clean in most situations that a boolean expression is expected, provided that its intent is clear.

Can we use ternary operator in if condition in Java?

Java ternary operator is the only conditional operator that takes three operands. It's a one-liner replacement for the if-then-else statement and is used a lot in Java programming. We can use the ternary operator in place of if-else conditions or even switch conditions using nested ternary operators.


1 Answers

I find that unnecessary usage of the ternary operator tends to make the code more confusing and less readable, contrary to the original intention.

That being said, the compiler's behaviour in this regard can easily be tested by comparing the bytecode as compiled by the JVM.
Here are two mock classes to illustrate this:

Case I (without the ternary operator):

class Class {      public static void foo(int a, int b, int c) {         boolean val = (a == c && b != c);         System.out.println(val);     }      public static void main(String[] args) {        foo(1,2,3);     } } 

Case II (with the ternary operator):

class Class {      public static void foo(int a, int b, int c) {         boolean val = (a == c && b != c) ? true : false;         System.out.println(val);     }      public static void main(String[] args) {        foo(1,2,3);     } } 

Bytecode for foo() method in Case I:

       0: iload_0        1: iload_2        2: if_icmpne     14        5: iload_1        6: iload_2        7: if_icmpeq     14       10: iconst_1       11: goto          15       14: iconst_0       15: istore_3       16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;       19: iload_3       20: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V       23: return 

Bytecode for foo() method in Case II:

       0: iload_0        1: iload_2        2: if_icmpne     14        5: iload_1        6: iload_2        7: if_icmpeq     14       10: iconst_1       11: goto          15       14: iconst_0       15: istore_3       16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;       19: iload_3       20: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V       23: return 

Note that in both cases the bytecode is identical, i.e the compiler disregards the ternary operator when compiling the value of the val boolean.


EDIT:

The conversation regarding this question has gone one of several directions.
As shown above, in both cases (with or without the redundant ternary) the compiled java bytecode is identical.
Whether this can be regarded an optimization by the Java compiler depends somewhat on your definition of optimization. In some respects, as pointed out multiple times in other answers, it makes sense to argue that no - it isn't an optimization so much as it is the fact that in both cases the generated bytecode is the simplest set of stack operations that performs this task, regardless of the ternary.

However regarding the main question:

Obviously it would be better to just assign the statement’s result to the boolean variable, but does the compiler care?

The simple answer is no. The compiler doesn't care.

like image 158
yuvgin Avatar answered Sep 28 '22 05:09

yuvgin