javaperformanceif-statementshorthandpremature-optimization

Which "if" construct is faster - statement or ternary operator?


There are two types of if statements in java - classic: if {} else {} and shorthand: exp ? value1 : value2. Is one faster than the other or are they the same?

statement:

int x;
if (expression) {
  x = 1;
} else {
  x = 2;
}

ternary operator:

int x = (expression) ? 1 : 2;

Solution

  • There's only one type of "if" statement there. The other is a conditional expression. As to which will perform better: they could compile to the same bytecode, and I would expect them to behave identically - or so close that you definitely wouldn't want to choose one over the other in terms of performance.

    Sometimes an if statement will be more readable, sometimes the conditional operator will be more readable. In particular, I would recommend using the conditional operator when the two operands are simple and side-effect-free, whereas if the main purpose of the two branches is their side-effects, I'd probably use an if statement.

    Here's a sample program and bytecode:

    public class Test {
        public static void main(String[] args) {
            int x;
            if (args.length > 0) {
                x = 1;
            } else {
                x = 2;
            }
        }
    
        public static void main2(String[] args) {
            int x = (args.length > 0) ? 1 : 2;
        }
    }
    

    Bytecode decompiled with javap -c Test:

    public class Test extends java.lang.Object {
      public Test();
        Code:
           0: aload_0
           1: invokespecial #1
           4: return
    
      public static void main(java.lang.String[]
        Code:
           0: aload_0
           1: arraylength
           2: ifle          10
           5: iconst_1
           6: istore_1
           7: goto          12
          10: iconst_2
          11: istore_1
          12: return
    
      public static void main2(java.lang.String[
        Code:
           0: aload_0
           1: arraylength
           2: ifle          9
           5: iconst_1
           6: goto          10
           9: iconst_2
          10: istore_1
          11: return
    }
    

    As you can see, there is a slight difference in bytecode here - whether the istore_1 occurs within the brance or not (unlike my previous hugely-flawed attempt :) but I would be very surprised if the JITter ended up with different native code.