Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speed of Comparison operators

In languages such as... well anything, both operators for < and <= (and their opposites) exist. Which would be faster, and how are they interpreted?

if (x <= y) { blah; }

or

if (x < y + 1) { blah; }

like image 218
bcc32 Avatar asked Jun 18 '11 20:06

bcc32


People also ask

Which one 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 ===.

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.

What are the 2 comparison operators?

Comparison OperatorsLess than ( < ) — returns true if the value on the left is less than the value on the right, otherwise it returns false . Greater than ( > ) — returns true if the value on the left is greater than the value on the right, otherwise it returns false .


3 Answers

Assuming no compiler optimizations (big assumption), the first will be faster, as <= is implemented by a single jle instruction, where as the latter requires an addition followed by a jl instruction.

http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Jump_if_Less

like image 95
Ben Hocking Avatar answered Oct 14 '22 00:10

Ben Hocking


I wouldn't worry about this at all as far as performance goes. Using C as an example, on a simple test I ran with GCC 4.5.1 targeting x86 (with -O2), the (x <=y ) operation compiled to:

    // if (x <= y) {
    //     printf( "x <= y\n");
    // }
    //
    // `x` is [esp+28]
    // `y` is [esp+24]

    mov eax, DWORD PTR [esp+24]     // load `y` into eax 
    cmp DWORD PTR [esp+28], eax     // compare with `x`
    jle L5                          // if x < y, jump to the `true` block
L2:

    // ...

    ret

L5: // this prints "x <= y\n"
    mov DWORD PTR [esp], OFFSET FLAT:LC1
    call    _puts
    jmp L2      // jumps back to the code after the ` if statement

and the (x < y + 1) operation compiled to:

    // if (x < y +1) {
    //     printf( "x < y+1\n");
    // }
    //
    // `x` is [esp+28]
    // `y` is [esp+24]

    mov eax, DWORD PTR [esp+28]     // load x into eax
    cmp DWORD PTR [esp+24], eax     // compare with y
    jl  L3                          //  jump past the true block if (y < x)
    mov DWORD PTR [esp], OFFSET FLAT:LC2
    call    _puts
L3:

So you might have a difference of a jump around a jump or so, but you should really only be concerned about this kind of thing for the odd time where it really is a hot spot. Of course there may be differences between languages and what exactly happens might depend on the type of objects that are being compared. But I'd still not worry about this at all as far as performance is concerned (until it became a demonstrated performance issue - which I'll be surprised if it ever does for more than once or twice in my lifetime).

So, I think the only two reasons to worry about which test to use are:

  • correctness - of course, this trumps any other consideration
  • style/readabilty

While you might not think there's much to the style/readability consideration, I do worry about this a little. In my C and C++ code today, I'd favor using the < operator over <= because I think loops tend to terminate 'better' using a < than a <= test. So, for example:

  • iterating over an array by index, you should typically use an index < number_of_elements test
  • iterating over an array using pointers to elements should use a ptr < (array + number_of_elements) test

Actually even in C, I now tend to use a ptr != (array + number_of_elements) since I've gotten used to STL iterators where the < relation won work.

In fact, if I see a <= test in a for loop condition, I take a close look - often there's a bug lurking. I consider it an anti-pattern.

Noe I'll grant that a lot of this may not hold for other languages, but I be surprised if when I'm using another language that there's ever a performance issues I'll have to worry about because I chose to use < over <=.

like image 3
Michael Burr Avatar answered Oct 14 '22 00:10

Michael Burr


What data-type?

If y is INT_MAX, then the first expression is true no matter what x is (assuming x is the same or smaller type), while the second expression is always false.

If the answer doesn't need to be right, you can get it even faster.

like image 2
Ben Voigt Avatar answered Oct 14 '22 00:10

Ben Voigt