For loop vs forEach производительность в javascript и достоверность результатов jsperf
Я не верю результатам измерения производительности jsperf для цикла vs forEach. По крайней мере, для chrome и firefox на моей машине результаты полностью отличаются от тех, которые рекламируются в jsperf.
http://jsperf.com/foreach-vs-loop (мой)
http://jsben.ch/#/BQhED (более популярным)
На моем ноутбуке под управлением Ubuntu 11.10 у меня есть следующие результаты в Firefox:
for: total=1641 ms, avg=164.1 ms
forEach: total=339 ms, avg=33.9 ms
uname -a:
Linux 3.0.0-16-generic #29-Ubuntu SMP Tue Feb 14 12:48:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
К сожалению, Chrome не возвращает результат console.timeEnd(), но время работы такое же и только быстрее в Chrome. Я наблюдаю, что forEach почти в 10 раз быстрее, чем для цикла в Chrome, и в 3 раза быстрее в Firefox.
В Chrome я получаю примерно следующее время:
for: avg=80 ms
forEach: avg=6 ms
Здесь код, который я запускал в Firefox и консоли Chrome.
var arr = [];
for(var i = 0; i < 100000; i++) arr[i]=i;
var numberOfRuns = 10;
function time(name, f){
console.time(name);
f();
return console.timeEnd(name);
}
function runTest(name, f){
var totalTime = 0;
for(var r = 0; r < numberOfRuns; r++)
totalTime += time(name,f);
return totalTime;
}
var forTime = runTest('for', function(){
for(var j = 0; j < arr.length; j++)
arr[j];
});
var forEachTime = runTest('forEach', function(){
arr.forEach(function(v){v;});
});
console.log('for', {total:forTime, avg:forTime / numberOfRuns});
console.log('forEach', {total:forEachTime, avg:forEachTime / numberOfRuns});
Запуск тестов на один миллион элементов имеет ту же разницу в производительности. Не могли бы вы посоветовать, если мне что-то не хватает, и я должен доверять результатам jsperf вместо реальных, которые я наблюдаю? Конечно, я доверяю реальным результатам, которые я вижу прямо сейчас в своем браузере.
EDIT: тестовый сценарий не является объективным, как обнаружено во время обсуждения с @Blender. Похож на оптимизатор js optimezes forEach, без каких-либо действий в нем, и, таким образом, затеняет время выполнения, если существует какой-то реальный код.
Ответы
Ответ 1
Я изменил ваш код, чтобы быть более справедливым. Вы можете взглянуть на него?
var arr = [];
for (var i = 0; i < 100000; i++) arr[i] = i;
var numberOfRuns = 100;
function runTest(name, f) {
var totalTime = 0;
console.time(name);
for (var r = 0; r < numberOfRuns; r++) {
f();
}
return console.timeEnd(name);
}
function testFunction(v) {
v;
}
var forTime = runTest('for', function() {
for (var j = 0; j < arr.length; j++) {
testFunction(arr[j]);
}
});
var forEachTime = runTest('forEach', function() {
arr.forEach(testFunction);
});
Ответ 2
Вот реальный тест: http://jsfiddle.net/ssSt5/57/ (запустите его несколько раз)
По-видимому, они практически одинаковы.
Итак, когда происходит реальное вычисление, for vs forEach
не имеет значения. Другие факторы оказывают гораздо большее влияние на производительность. Специально после того, как время выполнения применено к оптимизации.
Ответ 3
На этом сайте показаны результаты для полного диапазона подходов к циклу JavaScript http://www.jsbenchmarks.com/?anywhichway/loop/master/benchmark.js. Результаты - это среднее значение для всех посетителей сайта, на которых выполняется эталон, по сравнению с вашим собственным, если вы решите запустить тест.