2011-11-08 5 views
32

JavaScriptでは、二重使用(==)と三重等価(===)を使用した場合のパフォーマンスの違いはありますか?二重等価(==)と三重等価(===)との間のJavaScriptのパフォーマンスの差異

例:if (foo == bar)による性能へif (foo === bar)

+20

これまでに気付くことはありません。進む。 –

+2

これらは異なる目的を果たしており、「より多くのパフォーマンス」はその1つではありません。これは問題ではなく、提供している機能を取得したいときに使用します。 – meagar

+0

推奨読書:[あなたはJSを知らない](https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&%20grammar/ch4.md#loose-equals-vs -strict-equals) –

答えて

25

厳密な比較(===)よりも多くのものをチェックする必要があります。

比較でタイプ強制を必要としないことがわかっている場合は、間違いなく===を好むことは間違いありません。常に最低でも==となります。

+3

おかしい、 '=='ビート '==='私のために、私はFF7で両方の時間にテストを走った。私は '==='が速くなければならないことに同意するだろうが、テストでは別段の主張がある。 (おそらくJavascriptエンジン/ CPU負荷の不一致、誰が知っていますか) – Nightfirecat

+0

@Nightfirecat:それは面白いです。変数やリテラルを比較していましたか? –

+0

私が使用したデフォルトのテスト、つまり「==/===同じタイプのみ」のテストを使っていました。その中で最も速いテストでした。私は、同じパターンが定期的な比較テストとは対照的にバイタイプ比較のすべてに現れたと思いますが、覚えていません。 – Nightfirecat

3

対、私は

例えば、=====よりも厳しいですので===は、優れた性能を持っていると思いますChromeコンソールで次の操作を試してください。

> 1 == '1' 
    true 
> 1 === '1' 
    false 

==

は常にわずかに速いが、 the difference is usually negligibleなります ===

1

いくつかの弱いテストから、=====よりやや速いと思われます。

私は、数百万回のテストの中断で数ミリ秒の違いが見られることを意味します。手元の作業に最も適したものを使用するのではなく、パフォーマンスの向上が必要なことはありません。

EDIT:実際には、/あなた/ブラウザの実装と比較しているようです。つまり、心配しないでください。比較のタイプが同じである場合

+1

'==='はほとんどの場合、より高速です。エッジケースがあります(見つけました)。しかし、コード実行/スタイルガイド '==='からは、毎回 – Raynos

+2

"それを心配しないでください"、 "パフォーマンスの向上は必要ないでしょう。このユーザーと、この質問のためにここに来るすべてのユーザーの意図はわかりません。 – cdosborn

+2

@cdosborn woah、hello 2011.このQはSOのnodejsタグの日付より前です。はい。それで合っています。当時はこれがブラウザにあったことを正当に前提としていたため、数ミリ秒/数百万回の評価は、あなたの時間を悪用していました。物事は〜5年で多く変わった。 – Hamish

38
  • は、は彼らが同じです。すなわち、それらは正確に同じアルゴリズムを使用してを使用します。

  • タイプがと異なる場合、の場合、パフォーマンスは関係ありません。あなたは型強制を必要とするか、そうでないかのどちらかです。必要がない場合は、==を使用しないでください。結果が予期しない可能性があります。

14

編集:参照用は、ここで博士アクセルRauschmayer http://www.2ality.com/2011/06/javascript-equality.html 本当に素晴らしい、ライトアップにより、スペック説明によるです。

===(厳密な等式):同じ型の等しい値のみを考慮します。

  1. 未定義===未定義、ヌル=== nullで、
  2. NaNを===自身も含め何も、
  3. プリミティブ[番号|文字列|ブール] ===等しいプリミティブ値、
  4. 自己へ(+0 === -0)
  5. 2つのオブジェクト[アレイ|オブジェクト|機能] ===、自己(まったく同じエンティティ)

==(寛容平等)

  1. 両方の値が同じタイプの場合:===と比較してください。
  2. 未定義== NULL
  3. 数と列:文字列=>数と数に
  4. ブールおよび非ブール=>非ブール値を比較し、
  5. 文字列または数値=>オブジェクトを比較する:変換オブジェクトプリミティブと比較。

最新のJavascript環境では、これらはすべて完全に異なって実装されています。簡単に言えば、==は、与えられた変数をプリミティブ(文字列、数値、ブール値)に変換することによってalikenessをテストします。 ===は厳密な同一性をテストします。これは変換なしで全く同じObjectまたはプリミティブ値を意味​​します。

あなたが実際に何が起こるか objOne == objTwo はJSとエンジン内部のものにさらさ関数間でバウンス、 [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

のvalueOfの解像度がやや複雑になることがあるんならば。比較では、常に2つの値がプリミティブに強制されるか、エラーがスローされることになります。

編集:EQUALSは、最初にSTRICT_EQUALSを試行して残りのプロセスを優先します。

ここで興味深いのは、valueOf(およびそのパートナーtoString)がオーバーライド可能であることです。 Chromeでこのコードを実行してください(JSCとV8がこの楽しいことを分かち合っているかどうかはわかりません)。それはあなたのmindpieceを爆破する:

var actions = []; 
var overload = { 
    valueOf: function(){ 
    var caller = arguments.callee.caller; 
    actions.push({ 
     operation: caller.name, 
     left: caller.arguments[0] === this ? "unknown" : this, 
     right: caller.arguments[0] 
    }); 
    return Object.prototype.toString.call(this); 
    } 
}; 
overload.toString = overload.valueOf; 
overload == 10; 
overload === 10; 
overload * 10; 
10/overload; 
overload in window; 
-overload; 
+overload; 
overload < 5; 
overload > 5; 
[][overload]; 
overload == overload; 
console.log(actions); 

出力:

[ { operation: 'EQUALS', 
    left: overload, 
    right: 10 }, 
    { operation: 'MUL', 
    left: overload, 
    right: 10 }, 
    { operation: 'DIV', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'IN', 
    left: overload, 
    right: DOMWindow }, 
    { operation: 'UNARY_MINUS', 
    left: overload, 
    right: undefined }, 
    { operation: 'TO_NUMBER', 
    left: overload, 
    right: undefined }, 
    { operation: 'COMPARE', 
    left: overload, 
    right: 5 }, 
    { operation: 'COMPARE', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'ToString', 
    left: 'unknown', 
    right: overload } ] 

=====の違いの本質は、そのリストに表示されない===によって示されています。それはJavascriptLandへの旅を完全にスキップします。その冒険はパフォーマンスを比較すると高価です。

ただし、エンジンの最適化を考慮する必要があります。ほとんどのオブジェクトでは、エンジンはほとんどのステップをカットしてNativeLandにとどまり、ほぼ同じパフォーマンスを得ることができます。しかし、これは保証ではなく、エンジンが最適化を使用できないようにしたり、コード内のファンシー性を高めたり、組み込み関数や無数の問題をオーバーライドしたりすると、結果が即座にパフォーマンスに反映されます。 ===はそれを強制します。

===はJavascriptの唯一の不変なものです。

+0

これについてのあなたの証拠はどこですか?オペランドの型が同じ場合、 '=='と '==='が正確に同じように動作するように指定されているため、JS環境ではそれらを別々に実装することはできません。 –

+0

....最初の文の後に私のポストを読んだことはありますか?私はV8出力を文字通り含めました。短い答え:==呼===最初に===が真の場合、その差は無視できる。それを超えて==は定義によって失われます。 –

+0

そして、後世に注意するだけです。上の私の証拠は、私が思いついた斬新な方法です。これは、JSエンジンのオペレータ関数呼び出し元と、任意のJavaScriptオブジェクトからV8やJavaScriptCoreを使用しているすべての実装でオペランドが正しく配置されていることを識別でき、他の方法では不可能であり現在では他の方法ではうまく実装されていないJSにおけるオペレータのオーバーロードを直接的に可能にする。 –