3

I've heard compilers are very smart and know how to optimize if / else statements.

I've also heard ternaries are high performance because they go through the CPU's instruction pipeline less.

Let me clarify, based on what I've heard:

An if / else must pass its condition through the pipeline and wait for the result before it can perform the calculations for the outcome.

However a ternary can pass both the outcomes' calculations to the cpu without having to wait for the boolean expression to pass through the pipeline.

So, which is faster, ternaries or if / else ?

Magical Gordon
  • 404
  • 2
  • 8
  • It depends on the compiler. Some naive, non-optimizing compilers might conceivably use conditional moves for ternaries and branches for `if/else`, but any difference between the two is erased during a more sophisticated compiler's SSA transformation pass. – Iwillnotexist Idonotexist Jan 04 '16 at 21:09
  • 1
    At least in C, the semantics of `?:` forbid evaluation of the unselected side just as an `if() else` does. The compiler may evaluate both execution paths if and only if it complies with the as-if rule, i. e. the compiler can prove that the additional computation does not produce any observable side effects. Again, this is exactly the same situation for both `?:` and `if() else`. – cmaster - reinstate monica Jan 04 '16 at 21:10
  • @IwillnotexistIdonotexist A naive, non-optimizing compiler won't be able to prove that it is allowed to evaluate both paths. Therefore it must compile a `?:` without a conditional move. It is only the clever compilers that can prove such things and make use of a conditional move here. – cmaster - reinstate monica Jan 04 '16 at 21:14
  • @cmaster True; But I had in mind trivial `d = c ? a : b` examples where `a` and `b` are not side-effecting. Otherwise a full `if/else` is required. – Iwillnotexist Idonotexist Jan 04 '16 at 21:19
  • 1
    @IwillnotexistIdonotexist Yes, those "trivial" examples can be compiled with a move. However: Branching code can represent all instances of `?:`, conditional move code can't. So, a naive, non-optimizing compiler will always choose to compile all instances of `?:` into branching code, avoiding the hassle of deciding whether something better is possible. – cmaster - reinstate monica Jan 04 '16 at 21:35

1 Answers1

6

There will be no performance difference, ternary operator is just a syntactic sugar.

From ISO/IEC 9899 C Standard (draft, page 90):

6.5.15 Conditional operator

(...)

Semantics

The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below. (...)

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
  • 3
    Just to backup your answer: http://stackoverflow.com/questions/3565368/ternary-operator-vs-if-else – azngunit81 Jan 04 '16 at 21:06
  • From what the other answers say, they're only the same if the compiler is set to a certain optimization level. – Magical Gordon Jan 04 '16 at 21:17
  • 2
    @MagicalGordon They are the same; The only detail is that one (`if(c){a}else{b}`) is a statement while the other (`c ? a : b`) is an expression. The C Standard drafts describe the mechanics of `?:` exactly as an `if/else`: First the condition is evaluated, a sequence point occurs, and then either `a` or `b` but not both is evaluated. The compiler _can_ evaluate both if doing so has the same effect as only evaluating one by the _as-if_ rule; But if evaluating either causes side-effects then you can't do this. – Iwillnotexist Idonotexist Jan 04 '16 at 21:26
  • 1
    It depends what you mean by "the same" - the C standard mandates that they have the same effect - but of course compilers are free to implement one more efficiently than the other! There are plenty of cases where two constructs have identical observable behavior but compilers may implement them differently. For example, with no optimization flags, both `icc` and `clang` compile simple (side-effect free) ternaries with conditional moves, while ifs are compiled to jumps. Optimization changes thing and then they seem to prefer conditional moves regardless. – BeeOnRope Oct 28 '16 at 22:58
  • I checked on Compiler explorer, for most of the simple use cases the generated assembly is also exactly the same. One case I see better perf with ternary operator, while creating a heavy object(one with non-POD large memory footprint) we decide to initialize with ( object1 if condition true else object2). The only reason I can think of, because of default construction + copy assignment in case of if/else while only copy construction in ternary. But not very sure about this. – Anirudh Mar 24 '21 at 06:51