Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which operator is faster (> or >=), (< or <=)? [closed]

Is < cheaper (faster) than <=, and similarly, is > cheaper (faster) than >=?

Disclaimer: I know I could measure but that will be on my machine only and I am not sure if the answer could be "implementation specific" or something like that.

like image 272
Dimitar Slavchev Avatar asked Aug 01 '12 16:08

Dimitar Slavchev


People also ask

Which comparison operator is faster?

Some processors are quicker when comparing against zero. So > 0 might be faster than >= 1 , as an example. @Simple A decent compiler will replace >= 1 with > 0 if it's faster.

Is != Slower than ==?

What I meant is that the CPU could detect two values are not equal without looking at all bits, but it doesn't matter whether you use == or != to find that they are not equal, so the two operators are exactly equivalent. There is no reason to think one is faster than the other.

Which is faster === or ==?

So === faster than == in Javascript === compares if the values and the types are the same. == compares if the values are the same, but it also does type conversions in the comparison. Those type conversions make == slower than ===.

Are overloaded operators faster than functions?

"operator is always faster than a function" is just nonsense - especially so in C++ where invoking an operator is often just a syntactic sugar over calling a function.


1 Answers

TL;DR

There appears to be little-to-no difference between the four operators, as they all perform in about the same time for me (may be different on different systems!). So, when in doubt, just use the operator that makes the most sense for the situation (especially when messing with C++).

So, without further ado, here is the long explanation:

Assuming integer comparison:

As far as assembly generated, the results are platform dependent. On my computer (Apple LLVM Compiler 4.0, x86_64), the results (generated assembly is as follows):

a < b (uses 'setl'):

movl    $10, -8(%rbp)
movl    $15, -12(%rbp)
movl    -8(%rbp), %eax
cmpl    -12(%rbp), %eax
setl    %cl
andb    $1, %cl
movzbl  %cl, %eax
popq    %rbp
ret

a <= b (uses 'setle'):

movl    $10, -8(%rbp)
movl    $15, -12(%rbp)
movl    -8(%rbp), %eax
cmpl    -12(%rbp), %eax
setle   %cl
andb    $1, %cl
movzbl  %cl, %eax
popq    %rbp
ret

a > b (uses 'setg'):

movl    $10, -8(%rbp)
movl    $15, -12(%rbp)
movl    -8(%rbp), %eax
cmpl    -12(%rbp), %eax
setg    %cl
andb    $1, %cl
movzbl  %cl, %eax
popq    %rbp
ret

a >= b (uses 'setge'): 

movl    $10, -8(%rbp)
movl    $15, -12(%rbp)
movl    -8(%rbp), %eax
cmpl    -12(%rbp), %eax
setge   %cl
andb    $1, %cl
movzbl  %cl, %eax
popq    %rbp
ret

Which isn't really telling me much. So, we skip to a benchmark:

And ladies & gentlemen, the results are in, I created the following test program (I am aware that 'clock' isn't the best way to calculate results like this, but it'll have to do for now).

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

#define ITERS 100000000

int v = 0;

void testL()
{
    clock_t start = clock();
    
    v = 0;
    
    for (int i = 0; i < ITERS; i++) {
        v = i < v;
    }
    
    printf("%s: %lu\n", __FUNCTION__, clock() - start);
}

void testLE()
{
    clock_t start = clock();
    
    v = 0;
    
    for (int i = 0; i < ITERS; i++)
    {
        v = i <= v;
    }
    
    printf("%s: %lu\n", __FUNCTION__, clock() - start);
}

void testG()
{
    clock_t start = clock();
    
    v = 0;
    
    for (int i = 0; i < ITERS; i++) {
        v = i > v;
    }
    
    printf("%s: %lu\n", __FUNCTION__, clock() - start);
}

void testGE()
{
    clock_t start = clock();
    
    v = 0;
    
    for (int i = 0; i < ITERS; i++) {
        v = i >= v;
    }
    
    printf("%s: %lu\n", __FUNCTION__, clock() - start);
}

int main()
{
    testL();
    testLE();
    testG();
    testGE();
}

Which, on my machine (compiled with -O0), gives me this (5 separate runs):

testL: 337848
testLE: 338237
testG: 337888
testGE: 337787

testL: 337768
testLE: 338110
testG: 337406
testGE: 337926

testL: 338958
testLE: 338948
testG: 337705
testGE: 337829

testL: 339805
testLE: 339634
testG: 337413
testGE: 337900

testL: 340490
testLE: 339030
testG: 337298
testGE: 337593

I would argue that the differences between these operators are minor at best, and don't hold much weight in a modern computing world.

like image 106
Richard J. Ross III Avatar answered Nov 15 '22 15:11

Richard J. Ross III