Branches can be unpredictable and slow, no matter what instructions, (or tables, or whatever) are used to introduce the branch at question.
It is predictable nature of branching in this algo that makes the difference. Which makes me wonder...
EDIT: the cmov vs explicit branching story is a bit more complicated than just branch vs no branch.
It's true that the cmov instruction uses the CPU flags register (which I'm sure the CPU designers at Intel hate), but that doesn't mean that it branches.
You can achieve the same effect as cmov by using bitwise operations and a subtraction, though it'd just be a few cycles slower--but it would be even more clear that it doesn't branch.
for (step /= 2; step != 0; step /= 2) {
if (compare(begin[step], value))
begin += step;
}
Your comment, especially this part, made it click for me:> You can achieve the same effect as cmov by using bitwise operations and a subtraction, though it'd just be a few cycles slower--but it would be even more clear that it doesn't branch.
BTW, I hate how the author doesn't use braces with this `if` statement. Many a production bug, including one in OSX, as I recall, have occurred because someone didn't want to type a couple extra characters.
bool b = compare(begin[step], value);
begin += (step * b);