Sim*_*itt 6 c# performance x86 jit x86-64
这段代码怎么样:
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 Code Online (Sandbox Code Playgroud)
运行速度比此代码快3倍:
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;
Run Code Online (Sandbox Code Playgroud)
第一个代码片段执行完全相同的快速除法运算(即乘法然后右移),但也进行减法和乘法,但JIT编译器似乎产生较慢的代码.
我有每个可用的反汇编代码.
较慢的代码推送rbx寄存器并在开始时从rsp中减去10h,然后将其加回并在结束时弹出rbx,而较快的代码则不会.
较慢的代码也使用r11寄存器来处理更快的代码使用rdx的大多数事情.
有任何想法吗?
看来三元运算中使用的条件会影响生成的代码。
看起来三元选项生成的代码效率比简单的 if/else 低。
因此,将第二个片段中的循环代码更改为:
if (numerator >= 0) check += (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
else check += (int) -((-numerator * qdi.Multiplier) >> qdi.Shift);
Run Code Online (Sandbox Code Playgroud)
或者:
if (numerator < 0) check += (int) -((-numerator * qdi.Multiplier) >> qdi.Shift);
else check += (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
Run Code Online (Sandbox Code Playgroud)
或者:
check += numerator < 0
? (int) -((-numerator * qdi.Multiplier) >> qdi.Shift)
: (int) ((numerator * qdi.Multiplier) >> qdi.Shift);
Run Code Online (Sandbox Code Playgroud)
将产生运行速度更快的代码。
实际上,我觉得有点令人不安的是,四分之三的组合会产生快速的代码,但另一种会产生缓慢的代码......有时。