для цикла против производительности forEach в javascript и достоверности результатов jsperf - PullRequest
11 голосов
/ 17 марта 2012

Я не доверяю результатам измерения производительности jsperf цикла for 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 раз быстрее, чем цикл for в 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 вместо реальных результатов, которые я наблюдаю?Конечно, я доверяю реальным результатам, которые я вижу прямо здесь и сейчас в моем браузере.

РЕДАКТИРОВАТЬ: тестовый сценарий не является объективным, как было обнаружено во время обсуждения с @Blender.Похоже, что оптимизатор js optimezes для цикла forEach без каких-либо действий и, таким образом, затеняет время выполнения, если был какой-то реальный код.

Ответы [ 3 ]

9 голосов
/ 17 марта 2012

Я изменил ваш код, чтобы быть более справедливым.Вы можете взглянуть на это?

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);
});

Ваш тест не был обработан на 100% необработанным числом, поэтому некоторые браузеры несправедливо оптимизировали тест.

5 голосов
/ 20 мая 2016

Вот настоящий тест: http://jsfiddle.net/ssSt5/57/ (запустить его несколько раз)

Очевидно, что они практически одинаковы.1007 * не имеет значения.Другие факторы оказывают гораздо большее влияние на производительность.Особенно после того, как во время выполнения были применены оптимизации.

0 голосов
/ 05 января 2017

Этот сайт отображает результаты для всего спектра циклических подходов JavaScript http://www.jsbenchmarks.com/?anywhichway/loop/master/benchmark.js. Результаты - это среднее значение всех посетителей сайта, использующих тест, по сравнению с вашим собственным, если вы решите запустить тест.

...