I am writing an embedded C code. Which if condition would be faster/optimized:
if (a == false)
{
Some code
}
OR
if (a != true)
{
Some code
}
I am writing an embedded C code. Which if condition would be faster/optimized:
if (a == false)
{
Some code
}
OR
if (a != true)
{
Some code
}
If a
is of type bool
, you won't be able to spot a difference — probably even if you look at the assembly language code. Certainly, it is unlikely to be a measurable difference, especially if Some code
is more than a single instruction (or thereabouts). But only measurement or scrutiny of the assembly language can show you the difference.
If a
is of type int
(or any other non-bool
type), the conditions have different meanings and at most one of them is correct. The first is equivalent to a == 0
; the second is equivalent to a != 1
. Unless a
is restricted to the range 0
and 1
, the results are different when a
is 2
, for example.
The idiomatic test would be if (!a)
and that works the same for bool
and non-bool
types. You probably won't be able to spot any difference here, either.
Reading this question, the first thing that came to my mind is "That's ridiculous, the compiler knows better and will optimize it anyway, right?"
Well, turns out I was wrong, here is how MSVC /O2 compiles it:
With if (a == false)
:
84 C9 | test cl, cl
With if (a != true)
:
80 F9 01 | cmp cl, 1
Well, that's weird. Mike Nakis explained the difference between cmp
and test
in this answer. And Peter Cordes commented below:
There can be a perf difference on Intel Core2 or Nehalem, where TEST can macro-fuse with more flavours of JCC than CMP. e.g. Core2 and Nehalem can macro-fuse test eax,eax / js, but not cmp eax,0 / js. Nehalem can macro-fuse cmp eax,0 / jl, though. (Core2 can't, but Core2 can only macro-fuse at all in 32-bit mode).
I believe this is true, test
can be faster on some CPUs, but I don't believe its effect is measurable in practical scenarios.
Weirdly enough, for GCC, both -O2
and -O3
prefer cmp
over test
and will produce the same output for both cases.
Related: Test whether a register is zero with CMP reg, 0 vs OR reg, reg