Как этот код:
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;
может работать в 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;
Первый фрагмент кода выполняет точно такую же операцию быстрого деления ( это умножение, затем сдвиг вправо), но также вычитание и умножение, но JIT-компилятор, похоже, производит более медленный код.
У меня есть код дизассемблирования для каждого доступного.
Более медленный код сдвигает регистр rbx и вычитает 10h из rsp в начале, затем добавляет его обратно и выталкивает rbx в конце, тогда как более быстрый код этого не делает.
Более медленный код также использует регистр r11 для большинства вещей, где более быстрый код использует rdx.
Есть идеи?