for循环vs for jach javascript中的性能和jsperf结果的可信度

时间:2012-03-17 01:54:43

标签: javascript performance jsperf

我不相信jsperf测量for循环与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比Chrome中的循环快10倍,而Firefox则快3倍 在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 个答案:

答案 0 :(得分:9)

我修改了你的代码以使其更公平。你能看一下吗?

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%原始数字运算,因此某些浏览器对基准测试进行了不公平的优化。

答案 1 :(得分:5)

这是一个真正的测试:fillna(多次运行)

显然他们几乎是一样的。

因此,当进行实际计算时,DECLARE @Test TABLE ( T varchar(10), V int ); INSERT INTO @Test VALUES ('A', 4), ('B', -5), ('C', 5), ('A', 2), ('B', -1), ('C', 10), ('A', 2), ('B', -4), ('C', 5), ('D', 0); ;WITH CTE as ( select T,max(ABS(v ))v from @Test WHERE V <> 0 GROUP BY T ) SELECT T,V FROM @Test T where NOT exists (Select 1 FROM cte WHERE T = T.T AND v = ABS(T.V) ) ORDER BY T.T 并不重要。其他因素对绩效的影响要大得多。特别是在运行时应用了优化之后。

答案 2 :(得分:-1)

此网站显示了各种JavaScript循环方法http://www.jsbenchmarks.com/?anywhichway/loop/master/benchmark.js的结果。结果是运行基准测试的所有网站访问者与您自己选择运行基准测试的平均值。