4

私の調査により、for ループは JavaScript 言語で最速の反復構造であると信じています。forループの条件付き長さの値を宣言する方が速いと思っていました...明確にするために、次のうちどれが速いと思いますか?

例1

for(var i = 0; i < myLargeArray.length; i++ ) {
    console.log(myLargeArray[i]);
} 

例 2

var count = myLargeArray.length;
for(var i = 0; i < count; i++ ) {
    console.log(myLargeArray[i]);
} 

私の論理は、例1の各反復で、各反復でmyLargeArrayの長さにアクセスすると、例2のように単純な整数値にアクセスするよりも計算コストが高くなるということですか?

4

5 に答える 5

7

以下のいくつかのステートメントとは対照的に、配列の長さは各反復で計算されません。配列の長さは、poppushshiftunshiftなどの操作を変更することによって設定されるプロパティspliceです。

ただし、プロパティ ルックアップはローカル変数よりもコストが高いため、パフォーマンスがわずかに低下します。したがって、長さをキャッシュすることをお勧めします。ただし、巨大なデータセットを扱っていない限り、大きな違いは見られません。

ただし、反復ごとに長さが実際に計算される特殊なケースがあります。これは、HTML ノード コレクションの場合です。これらはライブ オブジェクトであるため、長さは配列の場合のプロパティではありません。これを行う場合:

for (var i=0; i < collection.length; i++) {
    collection[i]
};

次に、反復ごとにコレクションが解析されます。

for ループの最適化に関しては、通常、次のキャッシュ手法を使用します。

// if order is of no concern, just iterate from length-1 to 0
for (var i = arr.length - 1; i >= 0; i--){
    arr[i]
};

// use the for loop statement to set up scoped variables
for (var i=0, length = arr.length; i < length; i++) {
    // do something
}
于 2012-10-09T09:45:41.337 に答える
4

JavaScript Gardenから、JavaScript の癖に関する優れたリソース。

length プロパティは配列自体で定義されていますが、ループの反復ごとにルックアップを行うためのオーバーヘッドが依然としてあります。この場合、最近の JavaScript エンジンは最適化を適用する可能性がありますが、コードがこれらの新しいエンジンのいずれかで実行されるかどうかを判断する方法はありません。

于 2012-10-09T09:35:55.687 に答える
1

高性能JavaScriptから

反復ごとの作業を減らす:

//original loops
for (var i=0; i < items.length; i++){
process(items[i]);
}

var j=0;
while (j < items.length){
process(items[j++]]);
}

var k=0;
do {
process(items[k++]);
} while (k < items.length);



//minimizing property lookups
for (var i=0, len=items.length; i < len; i++){
process(items[i]);
}

var j=0,
count = items.length;
while (j < count){
process(items[j++]]);
}

var k=0,
num = items.length;
do {
process(items[k++]);
} while (k < num);


//minimizing property lookups and reversing
for (var i=items.length; i--; ){
process(items[i]);
}

var j = items.length;
while (j--){
process(items[j]]);
}

var k = items.length-1;
do {
process(items[k]);
} while (k--);

反復回数を減らす:

//credit: Jeff Greenberg
var i = items.length % 8;
while(i){
process(items[i--]);
}
i = Math.floor(items.length / 8);
while(i){
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
}

JavaScriptの最適化を参照してください

于 2012-10-09T10:33:37.780 に答える
1

毎回2番目のバージョンを使用しても失うものはないと思いますが、配列が実際にループによって変更されない限り、最初のアプローチで配列の長さが毎回ゼロから実際に計算された場合は驚くでしょう。

の最初の部分で複数の変数を宣言できることを忘れないでくださいfor

for(var i = 0, count = myLargeArray.length; i < count; i++ ) {
    console.log(myLargeArray[i]);
}
于 2012-10-09T09:33:21.503 に答える
0

はい、そうです myLargeArray.length はループの各反復で計算されています(最初の例)。リンク1 リンク 2

for(var i = 0; i < myLargeArray.length; i++ ) {
    console.log(myLargeArray[i]); 
} 
于 2012-10-09T09:31:06.870 に答える