How can this code:
var check = 0;
for (var numerator = 0; numerator <= maxNumerator; numerator++)
{
check += numerator >= 0
? numerator - (int) ((numerator * qdi.Multiplier) >> qdi.Shift) * qdi.Number
: numerator - (int) -((-numerator * qdi.Multiplier) >> qdi.Shift) * qdi.Number;
}
return check;
run 3x faster than this code:
var check = 0;
for (var numerator = 0; numerator <= maxNumerator; numerator++)
{
check += numerator >= 0
? (int) ((numerator * qdi.Multiplier) >> qdi.Shift)
: (int) -((-numerator * qdi.Multiplier) >> qdi.Shift);
}
return check;
The first code snippet does exactly the same fast divide operation (thats the multiply then shift right) but also a subtraction and multiplication but but the JIT compiler appears to be producing slower code.
I have the disassembly code for each available.
The slower code pushes the rbx register and subtracts 10h from rsp at the start and then adds it back and pops rbx at the end whereas the faster codes doesn't.
The slower code also uses the r11 register for most things where the faster code uses rdx.
Any ideas?
It would appear that the condition used in a ternary operation can affect the code generated.
It would also appear that a ternary optionation can generate less efficient code than a simple if/else.
So changing the loop code in the second snippest to:
if (numerator >= 0) check += (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
else check += (int) -((-numerator * qdi.Multiplier) >> qdi.Shift);
or:
if (numerator < 0) check += (int) -((-numerator * qdi.Multiplier) >> qdi.Shift);
else check += (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
or:
check += numerator < 0
? (int) -((-numerator * qdi.Multiplier) >> qdi.Shift)
: (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
will produce the faster running code.
Actually I find it a bit disturbing that three out of four combinations produce fast code but the other can produce slow code... sometimes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With