for-in ループは配列をループするよりも遅いことをいくつかの場所で読みました... sizeof (型) ブロックで前進することは、オブジェクトのキーを反復処理するために舞台裏で起こることと比較して、実質的に楽であることを理解しています、私はまだ興味があります、それがとても遅い正確な理由は何ですか...
キーを取得するために逆ハッシュ関数を実行する必要があり、そのプロセスが遅いのですか?
for-in ループは配列をループするよりも遅いことをいくつかの場所で読みました... sizeof (型) ブロックで前進することは、オブジェクトのキーを反復処理するために舞台裏で起こることと比較して、実質的に楽であることを理解しています、私はまだ興味があります、それがとても遅い正確な理由は何ですか...
キーを取得するために逆ハッシュ関数を実行する必要があり、そのプロセスが遅いのですか?
特定のエンジンの場合のこれに対する実際の答えは、そのエンジンの実装に依存する可能性があります。(違いがある場合は、その大きさも同様です。)
ただし、不変条件があります。たとえば、次のことを考慮してください。
var obj = {a: "alpha", b: "beta"};
var name;
for (name in obj) {
console.log(obj[name]);
}
var arr = ["alpha", "beta"];
var index;
for (index = 0; index < arr.length; ++index) {
console.log(arr[index]);
}
の場合obj
、エンジンはメカニズムを使用して、反復処理済みのプロパティと未処理のプロパティを追跡し、列挙不可能なプロパティを除外する必要があります。たとえば、舞台裏である種のイテレータ オブジェクトがあります (そして、仕様が定義されている方法で、一時的な配列である可能性があります)。
の場合、そうでarr
はありません。非常にシンプルで効率的な方法で、コードでそれを処理しています。
各ループのブロックの内容は同じです: オブジェクトのプロパティ ルックアップ。(後者の場合、理論上は数値から文字列への変換も行われます。)
したがって、これに対する実装固有ではない唯一の答えは、追加のオーバーヘッドです。
for..each
ループはイテレータとジェネレータを使用します。
next()
Iterator は、メソッドを持つオブジェクトです。Generator は、式を含むファクトリ関数ですyield()
。どちらの構成も、整数のインデックス変数よりも複雑です。
典型的なfor(var i = 0; i < arr.length; i++)
ループでは、ほぼすべての反復で実行される 2 つのコマンドはi++
とi < arr
です。next()
これは、関数呼び出し (または)を行うよりも間違いなくはるかに高速ですyield()
。
さらに、ループの開始 ( var i = 0
) も、メソッドでイテレーター オブジェクトを作成しnext()
たり、ジェネレーターを呼び出してイテレーターを作成したりするよりも高速です。ただし、それは実装に大きく依存しており、Javascript エンジンの作成者は、このような一般的に使用される言語機能を高速化するために最善を尽くしています。
違いはごくわずかなので、コードの他の部分の最適化に時間を費やしたいと思うかもしれません。構文の選択は、複雑さを増すためにパフォーマンスの向上が非常に小さい場合、パフォーマンスよりもコードの可読性と保守性を考慮する必要があります。そうは言っても、あなたや、あなたが裕福で有名になった後にあなたのコードを保守する他の開発者にとって、より意味のある構文を使用してください。;)