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 & ノードでは、最初のイテレーションは 2 回目のイテレーションよりも高速です。Safari と Firefox では、最初の反復は2 回目の反復よりも遅くなります。

ここにフィドルがあります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. 条件を使用しない"+bitwise" テスト ペアは、すべての主要なブラウザーの実行で (同じブラウザーの場合) 速度が同等です。(Chrome は FF よりも高速であり、ビット単位の操作では IE よりも高速です。他の SO の投稿を参照してください。)

  2. 条件を使用する「+cond」テスト ペアは大きな影響を受け、並べ替えられたデータは非常に有利です。これは、分岐予測が要因である場合に期待される結果です。

于 2012-10-10T23:20:07.800 に答える