web-dev-qa-db-ja.com

JavaScript-=== vs ==オペレーターのパフォーマンス

数週間前、私はこのスレッドを読みました <=?Cの比較演算子について。 <<=は同じ/類似のマシンコマンドとして解釈されるため、パフォーマンスに違いはないと言われています。

同時に、当社の「ベストプラクティス」では、「==」の代わりに「===」を使用して比較する必要があると言われていました。それで、私は「==」と「typeof ... ==」を使用することに慣れていて、私の書き方を変えたくないので、これが常に適切であるかどうか疑問に思い始めました:-]

これはJavaScriptのコンテキストであることに注意してください。

だから、私は少し研究をしていて、ここで JavaScriptの比較ではどちらの演算子(== vs ===)を使用する必要がありますか? それは言われています:

これは、等式演算子==が型強制を行うためです...つまり、インタープリターは暗黙的に値の変換を試みてから、比較を行います。

一方、恒等演算子===は型強制を行わないため、比較時に値の値を変換しません。

そして、これは、「===」演算子を使用すると、オペランドの変換にリソースが費やされないため、良好なパフォーマンスが得られることを意味するのだろうかと思い始めました。そして、すべてのコードがマシンコマンドに変換された後、これは、<<=を使用したときにCに違いがないのと同じように、JavaScriptやその他でも同じであることを意味しますか?言語?

26
gotqn

簡単に検証できる証拠を持った答えが最善だと思います。

これらの操作は非常に小さいため、パフォーマンステストを行うことは困難です。

  • == 1648真
  • === 1629 true
  • コントロールテスト1575true

コントロールテストを差し引くと、私のブラウザでは速度に最大30%の違いがあるように見えます。これを複数回行うと、さまざまな答えを得ることができますが、通常は===が最も速く表示されます。これは、違いがどれほど無視できるかを示す証拠にすぎないと思います。

これは、他の人が言っていたことをほぼ証明していると思います。パフォーマンスの違いは考えるのに時間の無駄ですしかし、===が実際に速いことも示しています。うまくいけば、この答えが他の人々、単に証拠を見なければならない人々の時間を節約することができます。

2019アップデート

2019-04-09テストが改善されたFirefox:

  • == 1383真
  • === 1167 true
  • コントロールテスト429true

2019-04-09 Chromeテストが改善されました:

  • == 249 true
  • === 248真
  • コントロールテスト248true

2019-04-09テストが改善されたエッジ:

  • == 22510 true
  • === 20315 true
  • コントロールテスト4968true

ブラウザは何年にもわたってよりスマートになり、私の元のテストはChromeとFirefoxのクールな最適化に対して実行され、もはや役に立たなくなったようです。テストを最適化するのがより難しくなり、増加しました再び意味のある結果を得るための実行回数。===は全体的にまだ高速であるように見えます。おそらく、心配するのはまだ時間の無駄です。

var testString = "42";
var testString2 = "43";
var testString3 = "42";
var testNumber = 42;
var testNumber2 = 43;
var testNumber3 = 42;

var testObject = {};
var testObject2 = {};
var testObject3 = testObject;


var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
        result = 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
        testString == testString3 && testNumber == testNumber3 && testObject == testObject3
}

console.log("==", Date.now() - start, result);

var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
        result =
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
        testString === testString3 && testNumber === testNumber3 && testObject === testObject3
}
console.log("===", Date.now() - start, result);
var start = Date.now();
var alwaysTrue = true;
var alwaysFalse = false;
for(var i = 0; i < 200000000; i++){
        result = 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysFalse || alwaysFalse || alwaysFalse || 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue && 
        alwaysTrue && alwaysTrue && alwaysTrue
}
console.log("control test", Date.now() - start, result);
16
Rick Velde

まず、パフォーマンスは単に問題ではありません。実際のスクリプトの場合、一方の演算子を他方よりも使用することによるパフォーマンスの向上は、コード内の他のボトルネックと比較して非常に小さくなります(通常、DOM操作が最大のターゲットになります)。

次に、多くの場合、=====まったく同じ手順を実行します。 2つのオペランドのタイプが同じである場合(たとえば、2つの文字列または2つの数値)、ECMAScript仕様は2つの演算子に対してまったく同じステップを持ちます。したがって、あるブラウザまたは他の環境で同じタイプのオペランドの2つの演算子のパフォーマンスの違いを観察した場合、別のブラウザでも同様の違いが見られることは保証されておらず、可能性もありません。

typeofの場合、あなたの質問で述べたように、2つのオペランドは同じ型(文字列)であることが保証され、両方の演算子はまったく同じことを行いますしたがって、ある演算子を他の演算子よりも優先するのは文体的です

JSコミュニティは全体として、これについてかなり厳しい状況にあります。コンセンサスは、「型強制が必要でない限り、==!=を使用しない」ようです。これは、私の好みにはあまりにも独断的です。

13
Tim Down

どのようなパフォーマンスが得られるかは関係ありません。この場合は、明らかに===の方が適しています。パフォーマンスの向上など、他のことはすべて、ケーキの上のアイシングです。その上、どちらの方法でも違いは最小限です。

4

パフォーマンスの違いはごくわずかです。つまり、貴重な脳のサイクルを無駄にしないでください。ただし、本当に知りたい場合は、テストする必要があります。

使用する ===そうしない大きな理由がない限り(おそらくそうしないでしょう)。

3
Triptych

それはスクリプト言語です。これらの演算子のパフォーマンスすべきではありません非常に重要なので、心配する必要があります。仮想マシンで実行されるという事実のように、はるかに多くの電力を消費するものが他にもたくさんあるからです。弱い型、ブラウザ内のHTMLDOMで動作します...

さらに、両方の演算子はまったく異なることを行うため、いずれの場合も一方を他方と交換できない可能性があります。

そうは言っても、私は===は高速です。その理由は、タイプを比較するだけでよく、一致する場合は生データを比較するためです。 ==演算子は、一致しない場合、あるタイプを別のタイプに変換しようとします。ほとんどの場合、これはよりコストのかかる操作になります。

そしてそれは幸運です。なぜならほとんどの場合===はより良いオプションです。 :)

とにかく、簡単にテストできます(同じタイプといくつかの異なるタイプの両方で、複数のケースをテストするようにしてください)が、テスト方法がわからない場合は、まったく心配する必要はありません。違いがあったとしても、あなたを殺すことはありません。

3
GolezTrol