Which is faster relational operator or equality operator? 
Author Message
 Which is faster relational operator or equality operator?

Which one of these is more efficient, if any?

if(foo() < 0) ...

if(foo() == -1) ...

Assume the compiler is gcc.

I have always wondered about this as it's such a common pattern that even if the
difference were only slight it would be worth doing the most effecicient way.

     -Vance



Mon, 08 Aug 2005 02:28:16 GMT  
 Which is faster relational operator or equality operator?

Quote:

> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

> Assume the compiler is gcc.

Benchmarking is your friend.  But if I had to guess, I'd think
the first one, because I'd expect more architectures to be able
to easily test the sign of a number than equality with a
particular constant.

In particular, on x86 test-and-branch on a register for a
negative value takes 4 bytes:
   0:   09 c0                   or     %eax,%eax
   2:   78 08                   js     c <label>
whereas a test-and-branch against -1 takes 10 bytes:
   4:   39 05 ff ff ff ff       cmp    %eax,0xffffffff
   a:   74 00                   je     c <label>
(unless there's a better opcode than `cmp %eax,-1', which there
very well may be since I'm kind of out of the assembly game).

On the other hand, if the value in the register won't be used
again, you can do better with a test-and-branch against -1, with
only 3 bytes:
   c:   40                      inc    %eax
   d:   74 00                   je     f <label>

But it's kind of pointless to speculate like this, since you
might not even be using x86.  Plus, the actual timings of the
instructions above will depend on their context and on the
particular process and for all I know on the phase of the moon as
well.
--
"Some people *are* arrogant, and others read the FAQ."
--Chris Dollin



Mon, 08 Aug 2005 02:39:35 GMT  
 Which is faster relational operator or equality operator?


Quote:
> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

> Assume the compiler is gcc.

> I have always wondered about this as it's such a common pattern that even
if the
> difference were only slight it would be worth doing the most effecicient
way.

>      -Vance

Definitely the first if you had a condition where foo() never gave -1, it
might follow the sequence ...,6,4,2,0,-1,-4,...
I always use the former as it is inherantly better for error checking
Allan


Mon, 08 Aug 2005 02:51:38 GMT  
 Which is faster relational operator or equality operator?

Quote:



> > Which one of these is more efficient, if any?

> > if(foo() < 0) ...

> > if(foo() == -1) ...

> > Assume the compiler is gcc.

> Definitely the first if you had a condition where foo() never gave -1, it
> might follow the sequence ...,6,4,2,0,-1,-4,...

If foo() never returns -1 then it's not going to follow that
sequence.  But in any case, there are many functions in the UNIX
API that are defined to return a value -1 or greater, where -1 is
the error indication.
--
"I don't have C&V for that handy, but I've got Dan Pop."
--E. Gibbons


Mon, 08 Aug 2005 03:03:19 GMT  
 Which is faster relational operator or equality operator?

Quote:

> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

> Assume the compiler is gcc.

(1) We try to avoid any assumptions about particular compilers.  CLC is
about C, not gcc (or MSC or Borland or ICC or LCC or ...)
(2) If there is a difference (on the assumption that foo() == -1 whenever
foo() < 0), it is likely to be related to your hardware, not the compiler
(3) There is not likely to be any difference, except the if(foo() < 0)
doesn't lock you into exactly one possible negative value.


Mon, 08 Aug 2005 03:24:08 GMT  
 Which is faster relational operator or equality operator?


Quote:



> > > Which one of these is more efficient, if any?

> > > if(foo() < 0) ...

> > > if(foo() == -1) ...

> > > Assume the compiler is gcc.

> > Definitely the first if you had a condition where foo() never gave -1,
it
> > might follow the sequence ...,6,4,2,0,-1,-4,...

> If foo() never returns -1 then it's not going to follow that
> sequence.

oops, typo, that should have been ...,6,4,2,0,-2,-4,...
Allan

- Show quoted text -

Quote:
> But in any case, there are many functions in the UNIX
> API that are defined to return a value -1 or greater, where -1 is
> the error indication.
> --
> "I don't have C&V for that handy, but I've got Dan Pop."
> --E. Gibbons



Mon, 08 Aug 2005 03:51:57 GMT  
 Which is faster relational operator or equality operator?

Quote:

> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

Out of curiosity, why does the question even arise? If `foo' returns a
negative, but otherwise unspecified value on some condition, use the first.
If `foo' returns -1 on some condition (e.g. many POSIX functions do this to
indicate an error), use the second.

Martin



Mon, 08 Aug 2005 04:54:56 GMT  
 Which is faster relational operator or equality operator?

Quote:

>> Which one of these is more efficient, if any?

>> if(foo() < 0) ...

>> if(foo() == -1) ...
> Out of curiosity, why does the question even arise? If `foo' returns a
> negative, but otherwise unspecified value on some condition, use the first.
> If `foo' returns -1 on some condition (e.g. many POSIX functions do this to
> indicate an error), use the second.

Presumably it arises from a teeth-skin feeling that "I have to get this
code as fast as it can possibly go, no matter the cost!".
When you are thinking of optimisation, first ask yourself whether you
really need to optimise at all. Then first try to macro-optimise, i.e.
optimise the algorithm. Only at a last resort try to micro-optimise,
i.e. optimise individual instructions.

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"A friend of mine is into Voodoo Acupuncture. You don't have to go into her
office. You'll just be walking down the street and... ohh, that's much better!"
   - Stephen Wright



Mon, 08 Aug 2005 04:59:35 GMT  
 Which is faster relational operator or equality operator?

Quote:



>> Which one of these is more efficient, if any?

>> if(foo() < 0) ...

>> if(foo() == -1) ...

>> Assume the compiler is gcc.

>> I have always wondered about this as it's such a common pattern that even
> if the
>> difference were only slight it would be worth doing the most effecicient
> way.

>>      -Vance

> Definitely the first if you had a condition where foo() never gave -1, it
> might follow the sequence ...,6,4,2,0,-1,-4,...
> I always use the former as it is inherantly better for error checking
> Allan

On 2's-complement machines, it'd probably be faster the first way in all
cases, as it need only check the sign bit. The second way requires a full
bit-by-bit comparison.

--
Freenet distribution (temporary): http://24.25.175.161:8891/IoeuLVymsfM/
Olmstead's Law:
        After all is said and done, a hell of a lot more is said than done.



Mon, 08 Aug 2005 07:20:06 GMT  
 Which is faster relational operator or equality operator?


Quote:
> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

They don't do the same thing, so you cannot compare these.

Quote:
> Assume the compiler is gcc.

Why would you articially restrict yourself to one C compiler? And which
version anyway? PowerPC, Itanium, Alpha, ARM, x86 or what? Which
version? Do you think the version in five years will behave the same?

What makes you think it depends on the compiler? Isn't it much more
likely that this depends on the processor you are using? Again, if one
version runs faster today, why would you assume that the same is true
with next years processor? Do you intend to rewrite your code every
time?

Quote:
> I have always wondered about this as it's such a common pattern that even if
> the
> difference were only slight it would be worth doing the most effecicient way.

You are worrying about the wrong things. Neither way will make any
measurable difference. If you want to write efficient code, then (not
necessarily in that order)

   1. Learn how to write readable and bugfree code so that you have more
time to write efficient code.
   2. Learn how to use a profiler.
   3. Learn how to find which parts of a program are so fast that nobody
cares about their speed, and which ones are not.
   4. Learn about memory hierarchies.
   5. Learn how to write responsive code.

If you want to write useful code, then efficiency doesn't come first at
all. Writing software that is bugfree is important. Writing software
that is enjoyable to use is important. Writing software that is secure
can be very important. It isn't important how fast your software runs,
what counts is how fast the user can achieve what she or he wants to
achieve.



Mon, 08 Aug 2005 07:53:22 GMT  
 Which is faster relational operator or equality operator?

Quote:

> Which one of these is more efficient, if any?

>    if(foo() < 0) ...

>    if(foo() == -1) ...

> Assume the compiler is gcc.

> I have always wondered about this as it's such a common pattern that,
> even if the  difference were only slight,
> it would be worth doing the most efficient way.

It is implementation dependent.
Integral comparisons like this
are usually implemented as integral subtractions
followed by a jump which depends upon the resulting
status register flags (i.e.zero and negative).

         $ cat compare.c
         #include<stdio.h>
         extern int foo(void);

         int main(int argc, char* argv[]) {
           if (foo() == -1) {
             fprintf(stdout, "foo() == -1\n");
             }
           if (foo() < 0) {
             fprintf(stdout, "foo() < 0\n");
            }
           return 0;
           }

         $ gcc -O2 -Wall -ansi -pedantic -S compare.c
         $ cat compare.s
                 . . .
         call    foo    # eax <-- foo()
         incl    %eax   # ++eax
         je      .L4    # if (foo() == -1)
                 . . .

         call    foo    # eax <-- foo()
         testl   %eax, %eax
         js      .L5    # if (foo() < 0)

The comparisons themselves require exactly the same amount of time.
What costs is the branch which, if taken, forces the CPU
to flush the instruction queue and begin fetching instructions
at the branch target.  Apparently, my GNU C compiler
predicts by default that the condition will most likely be false
and branches only when the condition is true.



Mon, 08 Aug 2005 08:39:05 GMT  
 Which is faster relational operator or equality operator?

Quote:

> On 2's-complement machines,
> it'd probably be faster the first way in all
> cases, as it need only check the sign bit.

Is there some type of non 2's-complement machine
where it would be more complicated ?

--
pete



Mon, 08 Aug 2005 19:56:11 GMT  
 Which is faster relational operator or equality operator?


Quote:

> > Which one of these is more efficient, if any?

> > if(foo() < 0) ...

> > if(foo() == -1) ...

> > Assume the compiler is gcc.

> Benchmarking is your friend.  But if I had to guess, I'd think
> the first one, because I'd expect more architectures to be able
> to easily test the sign of a number than equality with a
> particular constant.

> In particular, on x86 test-and-branch on a register for a
> negative value takes 4 bytes:
>    0:   09 c0                   or     %eax,%eax
>    2:   78 08                   js     c <label>
> whereas a test-and-branch against -1 takes 10 bytes:
>    4:   39 05 ff ff ff ff       cmp    %eax,0xffffffff
>    a:   74 00                   je     c <label>
> (unless there's a better opcode than `cmp %eax,-1', which there
> very well may be since I'm kind of out of the assembly game).

   4: 83 f8 ff

is an alias shorter form of 'cmp    %eax,0xffffffff', which
sign-extends byte to a double-word. Also, instead of '0:' there
probably should be 'test     %eax,%eax', so that the register is not
written to. Anyway, as long as speed is concerned, though, there
shouldn't be a noticeable difference.

/BP



Tue, 09 Aug 2005 03:17:42 GMT  
 Which is faster relational operator or equality operator?

Quote:

> Which one of these is more efficient, if any?

> if(foo() < 0) ...

> if(foo() == -1) ...

> Assume the compiler is gcc.

> I have always wondered about this as it's such a common pattern that even if the
> difference were only slight it would be worth doing the most effecicient way.

>      -Vance

The question is flawed. I think you mean:

if (foo() < a) ...
if (foo() == b) ...

Because what you proposed used constants, and constant get optimizations that produce
results you didn't think of. For example, a < 0 can be done by checking the sign
bit.

Further, "assume the compiler is gcc" is meaningless. It depends on the base machine
and what assembly instructions are generated for it.

However, in general, the answer is "there is no difference". Virtually all such
comparisions (in the general case, not the constant case) are performed by a
machine subtract, either real or one that discards the result but keeps the flags.
The flag bits then determine if the operands are equal, less than, greater, etc.



Tue, 09 Aug 2005 16:01:38 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Equality '==' Operator

2. Compiler bug: pointer conversions from relational operator

3. Relational Operators' return types

4. Newbie question regarding strings and relational operators...

5. Question about int result of relational operator

6. relational operator q

7. Relational Operator Question

8. Does "pairing" relational operators make Operator Overloading safer?

9. comparision operator ignore type cast operators

10. Math operators is C. Exponent operator?

11. VC++ 5.0 ambiguity: conversion operator vs overloaded operator?

12. Comma operator in #define's (was Re: Usage of comma operator)

 

 
Powered by phpBB® Forum Software