Почему приращивающие операторы (++) с большими номерами имеют низкую производительность?
Я заметил, что при увеличении счетчика это значительно медленнее, когда значение счетчика является большим числом. Я пробовал его в Chrome, Firefox и IE11, все они показывают худшую производительность в больших количествах.
См. jsperf test здесь (код ниже):
var count1 = 0;
var count2 = new Date().getTime();
var count3 = 1e5;
var count4 = 1e9;
var count5 = 1e12;
var count6 = 1e15;
function getNum1() {
return ++count1;
}
function getNum2() {
return ++count2;
}
function getNum3() {
return ++count3;
}
function getNum4() {
return ++count4;
}
function getNum5() {
return ++count5;
}
function getNum6() {
return ++count6;
}
Почему это происходит?
Ответы
Ответ 1
Современные среды исполнения JavaScript и компиляторы выполняют оптимизацию SMI (Малые целые числа).
Все номера в JavaScript - это плавающие точки с двойной точностью, которые относительно медленны для выполнения вычислений. Однако на практике во многих случаях (например, в большинстве циклов for
) мы работаем с целыми числами.
Итак - очень полезно оптимизировать числа, чтобы выполнять эффективные вычисления, когда это возможно. Когда движок может доказать, что число является маленьким целым числом, он будет с удовольствием рассматривать его как таковой и выполнять все вычисления, как если бы число было целым числом.
Приращение 32-разрядного целого числа является однопроцессорной операцией и очень дешево. Таким образом, вы получаете лучшую производительность, делая это.
Ответ 2
Этот "большой" номер, который вы используете, действительно большой, я считаю, что это разница между обработкой 32-битного количества и количеством более 32 бит. Попробуйте базу 150000,00 (под 32-разрядной подписью), 3 000 000 000 (под 32-разрядный без знака) и 5 000 000 000 (более 32 бит).