2012-12-13 8 views
13

はなぜif (foo.bar !== undefined) {}よりも大幅に遅いif ('bar' in foo) {}をチェックして、基本的にJavascriptの "in"演算子が、厳密なメンバー比較と比べて一貫して遅いのはなぜundefinedですか?

http://jsperf.com/in-vs-member-object-accessを参照してください?

+0

[同様のベンチマーク結果](http://jsperf.com/in-versus-bracket-versus-dot) – bfavaretto

+0

私の結果は同じでした。しかし、 "in"の代わりに存在を確認する他の良い候補があります。http://jsperf.com/dictionary-contains-key – styfle

答えて

5

foo.bar !== undefinedは、それらの2つの値が一致するかどうかをチェックします。

fooのプロパティをループしてbarが含まれているかどうかを確認するためのメカニズムを使用する必要があります。ここで

は、生産関係式オペレータ

でザ・

ECMA-スクリプトから興味深い読むです:次のようにShiftExpressionにおける関係式が評価されています
1.関係式を評価します。
2. GetValue(Result(1))を呼び出します。
3. ShiftExpressionを評価します。
4. GetValue(Result(3))を呼び出します。
5. Result(4)がオブジェクトでない場合は、TypeError例外をスローします。
6. ToString(Result(2))を呼び出します。
7. Result(4)の[[HasProperty]]メソッドをパラメータResult(6)で呼び出します。
8.返品結果(7)。 !次のようにEqualityExpression ==関係式が評価されています:
1. EqualityExpressionを評価

厳格なん-等しくない演算子(!==)

生産EqualityExpression

2. GetValue(Result(1))を呼び出します。
3. RelationalExpressionを評価します。
4. GetValue(Result(3))を呼び出します。
5.比較結果(4)===結果(2)を実行します。 (下記参照)
6. Result(5)が真の場合はfalseを返します。それ以外の場合はtrueを返します。

+2

この情報をあなたの答えに直接インラインで投稿してくれてありがとう。私はすでに答えを受け入れていますが、本当にありがとうございます。私は他の人がそれを非常に価値があると感じるでしょう。 –

+0

この回答は間違っています。 'foo'に' bar'プロパティがあるかどうかを判断することは、両方の操作の第一歩です。 '' foo'の 'bar 'は' foo.bar!== undefined'のようにすることはできません。 inが遅いのは、それがあまり最適化されていないからです。 –

+0

@JasonOrendorff私は '' foo'の 'bar 'が' foo.bar!== undefined'と意味的にも実装の面でも同じであると確信していません。次のコード 'x = {};を考えてみましょう。 x.a =未定義; 'これら2つのステートメントを実行した後、 '( 'a' x)==(x.a!== undefined)'の結果はどのようなものになると思いますか?私は、現在の行動、「偽」は起こるべきことだと主張しますが、結果は「真」であるべきだと主張するようです。 –

4

あなたはそうです。 "bar" in foofoo.barより遅いのは意味がありません。

inの唯一の理由は、JITエンジニアからははるかに一般的なfoo.barの構文ほどの注目を受けていないということです。特にあなたのjsperf試験でケース内

、どこプロパティはfoo自体(ない試作品)に直接プロパティとして存在しない、それは'bar' in foofoo.bar !== undefinedより任意の遅くてはならないことを理にかなっています。何かあれば、それは速くなければならない。 2つの主な違いは、inにもプロパティの値をチェックせずに答えられることです!

foo.barのケースでは、V8エンジンとSpiderMonkeyエンジンの両方が、コードが何も役に立たない(つまり、観察可能な効果がない)ことを検出し、完全にそれを最適化することを期待しています。ベンチマークは実際の作業を測定していません。

明らかに、エンジンは、"bar" in fooを最適化するのに十分スマートではありませんが、それはほんの時間です。そして優先順位。

関連する問題