3

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

I usually write my equality conditions as:

if(0==x)

as many people do, instead of

if(x==0) 

so that the compiler will tell me when I accidentally type = instead of ==.

Someone told me that some compilers implement this as two register loads, instead of one using a not-equal-zero operation, and so it is less efficient.

Anyone know if this is a reasonable comment?

Community
  • 1
  • 1
Monty
  • 31
  • 1
  • 13
    Turn on your compiler warnings and write as you would in natural language (`x == 0`) before it's too late! – GManNickG May 26 '11 at 21:21
  • 4
    "as many people do" - I don't think so. – Xeo May 26 '11 at 21:21
  • 4
    Please identify this "someone". –  May 26 '11 at 21:24
  • @GMan A person with semitic or persian origins with right-to-left script will be much more comfortable with if (0 == x) :) (personally I prefer if (!x) – Zaur Nasibov May 26 '11 at 21:27
  • 1
    @Zaur: Languages other than English are banned. ;) – GManNickG May 26 '11 at 21:31
  • 5
    @Xeo this is an old and well-known technique, so "many people" is perfectly fair. – DNA May 26 '11 at 21:36
  • I added assembly level instructions (LLVM IR, since it's a bit higher level) to my previous answer: http://stackoverflow.com/questions/4624536/which-one-will-execute-faster-ifflag-0-or-if0-flag/4624821#4624821 Astonishingly, it produces exactly the same code... – Matthieu M. May 27 '11 at 07:28
  • @Xeo: To elaborate on @DNA comment, it's from ["Effective C++"](http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876/ref=sr_1_1?s=books&ie=UTF8&qid=1306538972&sr=1-1), pretty much **the** standard when it comes to what is considered C++ best practices. – casperOne May 27 '11 at 23:30

5 Answers5

9

Someone told me that some compilers implement this as two register loads, instead of one using a not-equal-zero operation

There is no technical reason to do this. So no, any compiler worth its salt will not make this irrelevant distinction: since both statements are strictly equivalent, and since this can be trivially recognized by the compiler, it will treat them identically.

Note that this is only true for built-in types and user-defined types with a well-behaved operator ==. Theoretically a user could provide an asymmetric operator == overload where this equivalence isn’t given.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 3
    Lies! `struct x {}; bool operator==(x, int) { return true; } bool operator==(int, x) { for (volatile int i = 1; i != 0;); }`. :P EDIT: Aw, ninja edited. :( – GManNickG May 26 '11 at 21:26
  • @GMan: I like the idea of that overload to stop people doing the yoda-conditions! – Xeo May 26 '11 at 21:28
4

Who knows what "some compilers" do, but in general, no, I wouldn't expect any difference whatsoever in the code generated by a reasonable compiler.

metamatt
  • 13,809
  • 7
  • 46
  • 56
0

I don't think so. The compiler will interpret that expression as a comparison and the effect will be the same. If the compiler is smart enough, it will detect that the 0 can be optimized.

What is important to take care is the order of the comparisons when you have more than one:

if(conditionA && conditionB && (conditionC || conditionD)) {...}

In this case, you should put the conditionA as the one that will cause the if to fail faster, instead of letting the execution analyze all other conditions and only then see that conditionA fails.

rambo
  • 418
  • 4
  • 16
0

Try writing small programs such as the one below, and you can determine which suits your needs. Are you looking for small code size, or fast execution?

#include <stdio.h>
#include <stdlib.h>

    int main(int argc, char *argv[]) {
        int x = atoi(argv[1]);
        int zeros=0;
        int i;
        for (i=0; i<100000; i++) {
            if (0==x) {
                zeros++;
            }
        }
        printf("zeros: %d\n",zeros);
        return 0;
    }
levis501
  • 4,117
  • 23
  • 25
  • On my machine, gcc yields an executable that is two bytes smaller for the (x==0) way; however the execution time is faster for the second method. – levis501 May 26 '11 at 21:40
  • Using -O4 optimization flag, both methods came out the same in terms of speed, even after increasing the loop size to 10000000. The (0==x) way had a smaller executable size. – levis501 May 26 '11 at 21:41
  • There's no point in comparing program sizes or execution times with non-optimized builds. – MSalters May 27 '11 at 07:55
  • @MSalters: For instructive purposes – levis501 May 27 '11 at 14:22
  • Your "benchmark" optimizes with GCC and clang into asm equivalent to `zeros = x ? 0 : 100000`, not looping. https://godbolt.org/z/qG8TnnEa5 . If you just want to look at the asm, there are vastly simpler test functions you could look at, no need for a pointless loop. – Peter Cordes May 10 '23 at 06:33
-1

Why not try to benchmak the 2 solutions ? :

#include <stdio.h>
#include <time.h>

#define LOOPS   1000000000

void main(void)
{
    clock_t start1, start2, end1, end2;
    int x=1,i;

    start1=clock();
    for(i=0;i<LOOPS;i++)
    {
        if (x==0)
        {
            x=1;
        }
    }
    end1=clock();

    start2=clock();
    for(i=0;i<LOOPS;i++)
    {
        if (0==x)
        {
            x=1;
        }
    }
    end2=clock();

    printf("x==0 %d ns\n", end1-start1);
    printf("0==x %d ns\n", end2-start2);
}
Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
  • 2
    For such a trivial change it's probably better just to look at the assembly. (Unless the performance difference really is huge, the difference in timing is just going to be noise.) – GManNickG May 26 '11 at 22:40
  • Your "benchmark" optimizes away those conditions, and in fact optimizes away `x` entirely because it's unused in any visible outputs / side effects. Also the loops themselves optimize away. https://godbolt.org/z/8hcPMocG8 . Like GManNickG said, look at the asm to verify that your compiler isn't garbage and makes the same asm for either way of writing the source, in some case of interest. (And no, disabling optimization wouldn't make this a useful benchmark. [Idiomatic way of performance evaluation?](https://stackoverflow.com/q/60291987)) – Peter Cordes May 10 '23 at 06:28