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
}
CodePudding user response:
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
CodePudding user response:
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.
CodePudding user response:
Same thing. Or just do if (!a) { /* code */ }
