Which one will execute faster, if (flag==0) or if (0==flag)?

Interview question: Which one will execute faster, if (flag==0) or if (0==flag)? Why?


Solution 1:

I haven't seen any correct answer yet (and there are already some) caveat: Nawaz did point out the user-defined trap. And I regret my hastily cast upvote on "stupidest question" because it seems that many did not get it right and it gives room for a nice discussion on compiler optimization :)

The answer is:

What is flag's type?

In the case where flag actually is a user-defined type. Then it depends on which overload of operator== is selected. Of course it can seem stupid that they would not be symmetric, but it's certainly allowed, and I have seen other abuses already.

If flag is a built-in, then both should take the same speed.

From the Wikipedia article on x86, I'd bet for a Jxx instruction for the if statement: perhaps a JNZ (Jump if Not Zero) or some equivalent.

I'd doubt the compiler misses such an obvious optimization, even with optimizations turned off. This is the type of things for which Peephole Optimization is designed for.

EDIT: Sprang up again, so let's add some assembly (LLVM 2.7 IR)

int regular(int c) {
  if (c == 0) { return 0; }
  return 1;
}

int yoda(int c) {
  if (0 == c) { return 0; }
  return 1;
}

define i32 @regular(i32 %c) nounwind readnone {
entry:
  %not. = icmp ne i32 %c, 0                       ; <i1> [#uses=1]
  %.0 = zext i1 %not. to i32                      ; <i32> [#uses=1]
  ret i32 %.0
}

define i32 @yoda(i32 %c) nounwind readnone {
entry:
  %not. = icmp ne i32 %c, 0                       ; <i1> [#uses=1]
  %.0 = zext i1 %not. to i32                      ; <i32> [#uses=1]
  ret i32 %.0
}

Even if one does not know how to read the IR, I think it is self explanatory.

Solution 2:

There will be no difference in your versions.

I'm assuming that the type of flag is not user-defined type, rather it's some built-in type. Enum is exception!. You can treat enum as if it's built-in. In fact, it' values are one of built-in types!

In case, if it's user-defined type (except enum), then the answer entirely depends on how you've overloaded the operator == . Note that you've to overload == by defining two functions, one for each of your versions!

Solution 3:

Same code for amd64 with GCC 4.1.2:

        .loc 1 4 0  # int f = argc;
        movl    -20(%rbp), %eax
        movl    %eax, -4(%rbp)
        .loc 1 6 0 # if( f == 0 ) {
        cmpl    $0, -4(%rbp)
        jne     .L2
        .loc 1 7 0 # return 0;
        movl    $0, -36(%rbp)
        jmp     .L4
        .loc 1 8 0 # }
 .L2:
        .loc 1 10 0 # if( 0 == f ) {
        cmpl    $0, -4(%rbp)
        jne     .L5
        .loc 1 11 0 # return 1;
        movl    $1, -36(%rbp)
        jmp     .L4
        .loc 1 12 0 # }
 .L5:
        .loc 1 14 0 # return 2;
        movl    $2, -36(%rbp)
 .L4:
        movl    -36(%rbp), %eax
        .loc 1 15 0 # }
        leave
        ret