10

编辑 在花费了几个小时并使用@pst 之后,事实证明问题完全不同。

在代码中,您可以看到我使用了“+new Date()”的时间戳快捷方式。这会像标准的“new Date().getTime()”一样返回一个时间戳。

但是,+new Date() 在与数学运算(+、-、/)一起使用时表现非常非常糟糕。尽管 'start' 变量的 typeof() 表示为 'number',但发生了一些事情让它变得非常缓慢。使用标准 getTime() 方法时,在进行时间减法时没有性能损失。

查看详细说明问题的 jsperf,http: //jsperf.com/new-date-timing 。

关于@pst 非常详细的答案以及我为复制链接问题所做的努力,请使用他的答案作为该问题的规范答案。

我将更改此问题的标题以准确反映@pst 的答案和我的初衷,但将保留原始标题和问题以供将来参考。

新问题

javascript 数组是否对随机排序和未排序数据的数组进行分支预测?

请参阅下面的@pst 的答案。

原始标题和问题如下

标题:数组迭代在相同数据上花费 2 倍的时间

我之前在看这个问题,为什么处理排序数组比处理未排序数组更快?,并想尝试在 javascript 中设置相同的测试。

这让我想到了一些意想不到的事情。在下面小提琴链接的测试中,简单地使用相同的代码迭代相同的随机生成的数值数组会导致响应时间大不相同。

我已经在 Chrome、Safari、Firefox 和 node.js 中对此进行了测试。

在 Chrome & node 中,第一次迭代比第二次迭代快。在 Safari 和 Firefox 中,第一次迭代比第二次迭代

这是小提琴,http://jsfiddle.net/9QbWB/6/

在链接的小提琴中,我禁用了排序(认为这最初是问题,但事实并非如此)。对数据进行排序使循环时间更长。

我已经非常彻底地检查了代码,以确保我已经删除了任何可能影响结果的内容。我感觉自己像是一组宣布 FTL 中微子的特殊科学家,我在实验中找不到问题,而且数据出乎意料。

在我下面包含的代码中,一些东西,如初始 setTimeout、jQuery DOM 可视化等,用于在 jsfiddle.net 中直观地显示数据。核心功能是一样的。

    //javascript test of https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array

setTimeout(function(){

    var unsorted_list = $('#unsorted'),
        sorted_list = $('#sorted');


    var length = 32768,
        data = [];

    for(var i=0; i<length; i++){
        data[i] = Math.floor( Math.random()*256); 
    }


    var test = function(){
        var sum = 0,
            start = +new Date();

        for(var i=0; i<1000; i++){
            for(var c=0; c<length; c++){
                if( data[c] >= 128 ){
                    //sum += data[c];
                }
            }
        }

        return +new Date() - start;
    }


    //Unsorted
    var results = 0;
    for( var i=0; i<10; i++){
        var x = test();
        console.log(x);
        unsorted_list.append('<div>'+x+'</div>');
        results += x;
    }
    unsorted_list.append('<div>Final:'+(results/10)+'</div>');
    console.log( 'Unsorted: ', results/10 );


    //Sort array
    //data.sort();

    //Sorted
    var results = 0;
    for( var i=0; i<10; i++){
        var x = test();
        console.log(x);
        sorted_list.append('<div>'+x+'</div>');

        results += x;
    }
    sorted_list.append('<div>Final:'+(results/10)+'</div>');
    console.log( 'Sorted: ', results/10 );

},5000);
4

1 回答 1

4

(显然这个答案错过了这个问题 - 出于相关原因留在这里。)


这是我的jsperf 案例 - http://jsperf.com/sorted-loop/2 - 也许更多的浏览器会显示足够的东西。我还包含了一个仅使用按位操作的测试用例,取自链接的帖子(我还没有验证 JS 中的有效性)。

结论:性能似乎与分支预测有关。

  1. 使用条件的“+按位”测试对在所有主要浏览器运行中的速度相同(对于同一浏览器)。(Chrome 比 FF 快,在按位操作上比 IE 快;请参阅其他 SO 帖子。)

  2. 使用条件的“+cond”测试对受到很大影响,排序后的数据受到高度青睐。如果分支预测是一个因素,这是预期的结果。

于 2012-10-10T23:20:07.800 回答