88

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;
Sled
  • 18,541
  • 27
  • 119
  • 168
Rogach
  • 26,050
  • 21
  • 93
  • 172
  • 35
    I'm guessing there's absolutely no difference. It's just syntax. Unless compilers are somewhat evil (or something else) and I'm wrong – sinelaw Jan 16 '11 at 16:58
  • 4
    Did you (micro)benchmark it? Share the results. – BalusC Jan 16 '11 at 16:59
  • 3
    Both will get jit'ed. There will be no difference at all. And don't bother decompiling the stuff. First thing that HotSpot does is to take out **all** optimizations that were applied by javac. – Ivo Wetzel Jan 16 '11 at 16:59
  • He's better off comparing the low-level bytecode. – James Jan 16 '11 at 17:00
  • The only thing you can say about the byte-code is whether it is the same. – Peter Lawrey Jan 16 '11 at 17:02
  • 1
    I'd suggest `int x=1; if (!expression) x++;` - no, even better, *stop* microoptimizations. – schnaader Jan 16 '11 at 17:02
  • 12
    They don't exist for different speeds. They exist for different purposes. I'm sure you understand the difference between statements and expressions. Statements perform actions. Expressions produce values. `if` is for use in statements. `?` is for use in expressions. – Mike Dunlavey Jan 16 '11 at 17:05
  • 1
    @schnaader everyone knows ++x; is faster than x++ :P Besides, that code would actually be slower as it involves (when expression is false) 2 writes, a conditional jump and a read -- Compared to the original code where there was a condition jump, a write and a constant jump – James Jan 16 '11 at 17:12
  • 3
    +1 as the responses to this question are worth reading even if the intent of the original question is mis-guided. – jball Jan 16 '11 at 17:17
  • 2
    @James: You're right. So, lesson learned: **stop** microoptimization :) It won't change anything or even make things worse. – schnaader Jan 16 '11 at 17:23
  • 2
    @finnw - The downvotes are likely from developers who are weary of micro-optimization questions. Essentially they just amount to pontificating about things that have no real value in the real world. – JohnFx Jan 16 '11 at 18:05
  • If you are reading this, don't miss the [comment by James](https://stackoverflow.com/questions/4706696/which-if-construct-is-faster-statement-or-ternary-operator#comment27678765_4706785) – Not a bug May 29 '17 at 13:21
  • Regardless of which is faster, I would go for the `? :` because it is more readable and less verbose. – user16217248 Apr 15 '23 at 15:49

6 Answers6

108

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
10

Both of your examples will probably compile to identical or nearly identical bytecode, so there should be no difference in performance.

Had there been a difference in execution speed, you should still use the most idiomatic version (which would be the second one for assigning a single variable based on a simple condition and two simple sub-expressions, and the first one for doing more complex operations or operations that do not fit on a single line).

Victor Nicollet
  • 24,361
  • 4
  • 58
  • 89
8

These are the same. Both of them are fairly fast, typically around 10-30 nano-seconds. (depending on usage pattern) Is this time frame important to you?

You should do what you believe is clearest.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
4

Just to add to all the other answers:

The second expression is often called tertiary/ternary operator/statement. It can be very useful because it returns an expression. Sometimes it makes the code more clearer for typical short statements.

Secko
  • 7,664
  • 5
  • 31
  • 37
  • 4
    Great example of this in practice: in Java, if I have to make a String final based on the result of an expression, i can use the ternary syntax final String whichTable = (Integer.parseInt(clientId) > 500) ? "serverClients" : "offlineClients"; Then I can use the value of the expression in places where whichTable needs to be final. The following would be illegal: final String whichTable = ""; if (Integer.parseInt(clientId) > 500) { whichTable = "serverClients"; } else { whichTable = "offlineClients"; } – James Perih Sep 12 '13 at 20:48
  • @JamesPerih In the case of a `final` field, you could use constructor blocks to set a value (although the conditional operator looks a billion times better IMO), and with local variables, you could assign a value before first use later in the code block you're in. I think the only case where a ternary would give an advantage over `if-else` is when calling `super(...)` or `this(...)` inside a constructor. – Kröw Jan 27 '19 at 21:38
3

neither - they will be compiled to the same.

Freddie
  • 1,717
  • 2
  • 16
  • 23
0

Ternary operator is faster than if-else condition.

public class TerinaryTest {
    public static void main(String[] args)
    {
        int j = 2,i = 0;
        Date d1 = new Date();
        for(long l=1;l<100000000;l++)
            if(i==1) j=1;
                else j=0;
        Date d2 = new Date();
        for(long l=1;l<100000000;l++)
            j=i==1?1:0;
        Date d3 = new Date();
        System.out.println("Time for if-else: " + (d2.getTime()-d1.getTime()));
        System.out.println("Time for ternary: " + (d3.getTime()-d2.getTime()));
    }
}

Test Results:

Trail-1:

Time for if-else: 63

Time for ternary: 31

Trail-2:

Time for if-else: 78

Time for ternary: 47

Trail-3:

Time for if-else: 94

Time for ternary: 31

Trail-4:

Time for if-else: 78

Time for ternary: 47

rmkyjv
  • 35
  • 9
  • 1
    I had exactly the opposite results when running your example, which shows that the results are unreliable. Unfortunately you are falling into microbenchmarking trap - it is notoriously difficult to do microbenchmarks correctly. For a couple examples you can see here: https://stackoverflow.com/questions/2842695/what-is-microbenchmarking – Rogach Apr 28 '20 at 18:18
  • Your particular example suffers from a least these issues: 4 trials is nowhere enough, you run the tests in always the same order (first if-else, second ternary), you do not warm-up the JVM before running the tests, etc. – Rogach Apr 28 '20 at 18:20