0

私のページに次のJSがあるとしましょう(compare質問に関係のない単純なコンパレーター関数です):

    function sortArray(a) {
        a.sort(compare);
    }

    function sortJQuerySet(b) {
        b.sort(compare);
    }

    $(document).ready(function(){
        var a = [], b = [], i = 0, n = 1000;

        for(i=0; i<n; ++i) {
            a.push($('<div>' + i.toString() + '</div>'));
            b.push($('<div>' + i.toString() + '</div>'));
        }

        b = $(b);

        $('#runner').click(function(){
            sortArray(a);
            sortJQuerySet(b);
        });
    });

ご覧のとおり、abは本質的に同じ配列ですが、唯一の違いはbに変換されることjQuery setです。これらの配列の両方を並べ替え、並べ替えをプロファイルしようとしています。両方の配列の要素数が 1000 であることに注意してください。

以下は、Safari での両方のコンテナーの並べ替えのプロファイリングの結果です。 ここに画像の説明を入力

Safari は、1000 個の要素を持つ jQuery セットで約50 万回の比較を行います。これは、 O(n log n)ソートよりも 2 次ソートに似ています。当面の間、ネイティブ配列のソートは問題ありません。

Chrome ブラウザーでの並べ替えは、両方のコンテナー タイプでほぼ同じ時間で機能します。

PS Safari 6.0.4、jQuery 1.7.1、jQuery 1.10.1 を使用しました。コード: https://gist.github.com/ikostia/5925715

4

1 に答える 1

1

おそらく、WebKit エンジンに関するこの議論は、いくつかの光を当てる可能性があります。

次の行から私には見えます: 631 if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseMode()) { that only non-arrays, or arrays in some kind of "sparse" " モードは非効率的にソートされます。スパース モードが何かはわかりませんが、Raymond Chen にインスパイアされたサイキック パワーを試してみましょう: a[0]=1 と a[1000000]=2 を割り当てた場合、1 から 999999 までを保存したくありません。したがって、そのような配列は、整数をキーとするハッシュテーブルのように機能するスパースモードになります。同じことが非配列にも当てはまります...

(前述の引用で説明されているソース コードはこちら)

それでは、 jQuery のソース コードを見てみましょう。呼び出す$(someArrayOrSelectorString)と、initメソッドが呼び出されます (43 行目)。init メソッドは を返しますjQuery.makeArray( selector, this )。ここthisで、 は jQuery のインスタンスです (間違っていたら訂正してください)。最後に、makeArrayメソッド内でjQuery.merge(行 600) が呼び出され、渡された配列要素が jQuery インスタンスに入力されます。

したがって、配列をラップすると、配列のようなオブジェクト (jQuery インスタンス) が生成されますが、実際の配列ではないように見えます。そして、Safari はこのオブジェクトをスパース オブジェクトのように扱います。

(この回答とコメントに興味があるかもしれません。それが私の回答のアイデアを借りた場所です)

于 2013-07-09T10:11:12.840 に答える