2012-11-21 1 views
6

for-inループは配列をループするよりも遅いと読みました... sizeof(type)ブロックで前進することは、シーンの背後で何が起こってもオブジェクトのキー、私はまだ興味がありますが、正確な理由はそれが遅いということです...なぜfor-inはJavaScriptで遅いのですか?

キーを取得するために逆ハッシュ関数を実行する必要がありますか?そのプロセスは遅いですか?

+2

ええ、私は、キーを取得するのが相対的に遅いのと比較して、それを取得していないと推測しています;)for ... inは最初にキーをルックアップする必要があります。ループでは、ループ変数を通してキーを提供しています。 –

+2

これは 'for ... in'の実行が(少なくともChromeでは)' Object.keys() 'とほぼ同じであることを示すJSPerfテストです:http://jsperf.com/for-in- vs-keys-vs-forです。だから、キーやこれに関連するすべてを取得するのが遅くなり、外部からキーを提供することになります。しかし、T.J.と同様に、実装にも依存します。言った。 –

答えて

3

特定のエンジンの場合、これに対する実際の答えは、おそらくそのエンジンの実装に依存します。 (違いの大きさは、あれば)。

しかし、不変量があります。たとえば、考えてみます。

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の場合、そうではありません。非常にシンプルで効率的な方法でコード内で処理しています。

各ループのブロックの内容は同じです。オブジェクトに対するプロパティルックアップ。 (後者の場合、理論的には数値から文字列への変換もあります。)

したがって、実装に固有でない答えは次のとおりです。

1

for..eachループiterators and generatorsを使用します。

イテレータは、next()メソッドを持つオブジェクトです。 Generatorは、yield()式を含むファクトリ関数です。どちらの構文も整数インデックス変数よりも複雑です。

典型的なfor(var i = 0; i < arr.length; i++)ループでは、ほぼすべての反復で実行される2つのコマンドはi++i < arrです。おそらく、関数呼び出し(next()またはyield())よりもはるかに高速です。

さらに、ループ開始(var i = 0)は、next()メソッドを使用してイテレータオブジェクトを作成するか、ジェネレータを呼び出してイテレータを作成するよりも高速です。しかし、それは実装に大きく依存し、Javascriptエンジンの作成者は、よく使われる言語機能を加速するために最善を尽くす。

私は、コードの他の部分を最適化する時間を費やしたいと思うほど、その差はあまりないと言います。構文の選択は、コードの可読性とメンテナンス性を、パフォーマンスの向上が複雑さを増すほど小さい場合のパフォーマンスよりも考慮する必要があります。あなたが豊かで有名になった後、あなたとあなたのコードを維持する他の開発者にとってより意味のある構文を使用してください! ;)

関連する問題