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

C++C

C++ Problem Overview


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

C++ Solutions


Solution 1 - C++

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 - C++

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 - C++

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

Solution 4 - C++

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>.

Solution 5 - C++

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

Solution 6 - C++

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.

Solution 7 - C++

When in doubt benchmark it and learn the truth.

Solution 8 - C++

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
{

}

Solution 9 - C++

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...

Solution 10 - C++

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...

Solution 11 - C++

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);
}

Solution 12 - C++

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

Solution 13 - C++

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.

Solution 14 - C++

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.

Solution 15 - C++

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...

Solution 16 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVishwanath DalviView Question on Stackoverflow
Solution 1 - C++Matthieu M.View Answer on Stackoverflow
Solution 2 - C++NawazView Answer on Stackoverflow
Solution 3 - C++skcView Answer on Stackoverflow
Solution 4 - C++Linus KleenView Answer on Stackoverflow
Solution 5 - C++JonView Answer on Stackoverflow
Solution 6 - C++ds27680View Answer on Stackoverflow
Solution 7 - C++Elzo ValugiView Answer on Stackoverflow
Solution 8 - C++Matteo ItaliaView Answer on Stackoverflow
Solution 9 - C++dariooView Answer on Stackoverflow
Solution 10 - C++davkaView Answer on Stackoverflow
Solution 11 - C++Fanatic23View Answer on Stackoverflow
Solution 12 - C++Sachin ShanbhagView Answer on Stackoverflow
Solution 13 - C++Syntax_ErrorView Answer on Stackoverflow
Solution 14 - C++Marsh RayView Answer on Stackoverflow
Solution 15 - C++KindreadView Answer on Stackoverflow
Solution 16 - C++balkiView Answer on Stackoverflow