#javascript
#javascript
Вопрос:
Недавно я снова попал в ловушку преждевременной оптимизации и, надеюсь, выбрался обратно. Однако во время моего короткого перерыва я столкнулся с кое-чем, что я хотел бы подтвердить.
Мой самый простой тест производительности дал аналогичные результаты в Chrome (все переменные просто объявляются глобально, первая занимает ~ 9 мс, вторая ~ 7,5 мс):
input = Array.from({ length: 1000000 }, () => Math.random() > 0.8 ? 0 : Math.random() * 1000000000 );
start = performance.now();
for (let i = 0; i < 1000000; i ) {
input[i] = input[i] === 0 ? 0 : 1;
}
console.log(performance.now() - start);
и
input = Array.from({ length: 1000000 }, () => Math.random() > 0.8 ? 0 : Math.random() * 1000000000 );
start = performance.now();
for (let i = 0; i < 1000000; i ) {
input[i] = ((input[i] | (~input[i] 1)) >>> 31) amp; 1;
}
console.log(performance.now() - start);
Принимая во внимание, что сам цикл и назначение уже занимают много времени (~ 4,5 мс), второй потенциально занимает на ~ 33% меньше времени, что, однако, намного меньше, чем я ожидал (и в пределах погрешности измерения, например, в FireFox, оба занимают намного больше времени,и второй на ~ 33% хуже).
Могу ли я на данный момент заключить, что оптимизация условия уже выполняется, и аналогичное изменение кода уже выполняется, или я попадаюсь на какой-то мираж микробенчмарка? На мой взгляд, ветвь этой категории должна занимать чрезмерно больше времени, чем вычисление.
Я в первую очередь скептически отношусь к своим собственным рассуждениям, потому что знаю, что такого рода тесты могут очень легко иметь искаженные результаты по непредвиденным причинам.
Ответ №1:
Да, скорее всего, это результат сочетания эффектов измерения и JIT-компилятора.
Особенно хорошо, что JIT-компилятор, основанный на эвристике, в современных браузерах JS настолько хорош, что у вас не будет никаких шансов визуализировать «реальное» преимущество в производительности интуитивно более быстрого оператора.
Разница в моем браузере настолько велика, что обоим кодам требуется примерно одинаковое время (для запуска в Opera), что подчеркивает ваш эффект в FF.
Радуйтесь, что вы обнаружили это преимущество в 1,5 мс, большего вы не увидите.
Комментарии:
1. Я, вероятно, не буду использовать «оптимизацию», потому что она гораздо менее читабельна и не влияет на скорость, поэтому в пределах точности измерения (не могу определить, что быстрее). PS: читая связанную статью, я увидел
node --trace-opt --tracedeopt
и быстро заметил, что перенос цикла for в IIFE также ускоряет процесс, потому что из-заconsole.log
for me произошел шаг деоптимизации. Я еще больше убедился, что все это снова мираж, и на самом деле измерение того, что быстрее в реальном приложении, невозможно сделать с помощью того, что я сделал.