Vishwanath Dalvi
Vishwanath Dalvi

Reputation: 36681

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?

Upvotes: 112

Views: 26808

Answers (16)

Matthieu M.
Matthieu M.

Reputation: 300439

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.

Upvotes: 238

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361812

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!

Upvotes: 56

balki
balki

Reputation: 27684

If at all there was a difference, what stops compiler to choose the faster once? So logically, there can't be any difference. Probably this is what the interviewer expects. It is actually a brilliant question.

Upvotes: 0

Syntax_Error
Syntax_Error

Reputation: 6230

Build two simple programs using the suggested ways.

Assemble the codes. Look at the assembly and you can judge, but I doubt there is a difference!

Interviews are getting lower than ever.

Upvotes: 3

davka
davka

Reputation: 14702

Well, I am agreeing completely with all said in the comments to the OP, for the exercise sake:

If the compiler is not clever enough (indeed you should not use it) or the optimization is disabled, x == 0 could compile to a native assembly jump if zero instruction, while 0 == x could be a more generic (and costly) comparison of numeric values.

Still, I wouldn't like to work for a boss who thinks in these terms...

Upvotes: 5

Sachin Shanbhag
Sachin Shanbhag

Reputation: 55529

Surely no difference in terms of execution speeds. The condition needs to be evaluated in both cases in the same way.

Upvotes: 4

Kindread
Kindread

Reputation: 966

Just as an aside ( I actually think any decent compiler will make this question moot, since it will optimise it ) using 0 == flag over flag == 0 does prevent the typo where you forget one of the = ( ie if you accidently type flag = 0 it will compile, but 0 = flag will not ), which I think is a mistake everyone has made at one point or another...

Upvotes: 2

Fanatic23
Fanatic23

Reputation: 3428

Which one's fast depends on which version of == you are using. Here's a snippet that uses 2 possible implementations of ==, and depending on whether you choose to call x == 0 or 0 == x one of the 2 is selected.

If you are just using a POD this really shouldn't matter when it comes to speed.

#include <iostream>
using namespace std;

class x { 
  public:
  bool operator==(int x) { cout << "hello\n"; return 0; }
  friend bool operator==(int x, const x& a) { cout << "world\n"; return 0; } 
};

int main()
{ 
   x x1;
   //int m = 0;
   int k = (x1 == 0);
   int j = (0 == x1);
}

Upvotes: 5

Marsh Ray
Marsh Ray

Reputation: 2875

I think the best answer is "what language is this example in"?

The question did not specify the language and it's tagged both 'C' and 'C++'. A precise answer needs more information.

It's a lousy programming question, but it could be a good in the devious "let's give the interviewee enough rope to either hang himself or build a tree swing" department. The problem with those kinds of questions is they usually get written down and handed down from interviewer to interviewer until it gets to people who don't really understand it from all the angles.

Upvotes: 3

ds27680
ds27680

Reputation: 1993

Well there is a difference when flag is a user defined type

struct sInt
{
    sInt( int i ) : wrappedInt(i)
    {
        std::cout << "ctor called" << std::endl;
    }

    operator int()
    {
        std::cout << "operator int()" << std::endl;
        return wrappedInt;
    }

    bool operator==(int nComp)
    {
        std::cout << "bool operator==(int nComp)" << std::endl;
        return (nComp == wrappedInt);
    }

    int wrappedInt;
};

int 
_tmain(int argc, _TCHAR* argv[])
{
    sInt s(0);

    //in this case this will probably be faster
    if ( 0 == s )
    {
        std::cout << "equal" << std::endl;
    }

    if ( s == 0 )
    {
        std::cout << "equal" << std::endl;
    }
}

In the first case (0==s) the conversion operator is called and then the returned result is compared to 0. In the second case the == operator is called.

Upvotes: 12

Linus Kleen
Linus Kleen

Reputation: 34672

There is absolutely no difference.

You might gain points in answering that interview question by referring to the elimination of assignment/comparison typos, though:

if (flag = 0)  // typo here
   {
   // code never executes
   }

if (0 = flag) // typo and syntactic error -> compiler complains
   {
   // ...
   }

While it's true, that e.g. a C-compiler does warn in case of the former (flag = 0), there are no such warnings in PHP, Perl or Javascript or <insert language here>.

Upvotes: 27

Elzo Valugi
Elzo Valugi

Reputation: 27896

When in doubt benchmark it and learn the truth.

Upvotes: 11

skc
skc

Reputation: 561

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

Upvotes: 56

darioo
darioo

Reputation: 47213

As others have said, there is no difference.

0 has to be evaluated. flag has to be evaluated. This process takes the same time, no matter which side they're placed.

The right answer would be: they're both the same speed.

Even the expressions if(flag==0) and if(0==flag) have the same amount of characters! If one of them was written as if(flag== 0), then the compiler would have one extra space to parse, so you would have a legitimate reason at pointing out compile time.

But since there is no such thing, there is absolutely no reason why one should be faster than other. If there is a reason, then the compiler is doing some very, very strange things to generated code...

Upvotes: 5

Matteo Italia
Matteo Italia

Reputation: 126967

They should be exactly the same in terms of speed.

Notice however that some people use to put the constant on the left in equality comparisons (the so-called "Yoda conditionals") to avoid all the errors that may arise if you write = (assignment operator) instead of == (equality comparison operator); since assigning to a literal triggers a compilation error, this kind of mistake is avoided.

if(flag=0) // <--- typo: = instead of ==; flag is now set to 0
{
    // this is never executed
}

if(0=flag) // <--- compiler error, cannot assign value to literal
{

}

On the other hand, most people find "Yoda conditionals" weird-looking and annoying, especially since the class of errors they prevent can be spotted also by using adequate compiler warnings.

if(flag=0) // <--- warning: assignment in conditional expression
{

}

Upvotes: 7

Jon
Jon

Reputation: 437914

There will be absolutely no difference speed-wise. Why should there be?

Upvotes: 16

Related Questions