web-dev-qa-db-ja.com

Javascriptスイッチとif ... else if ... else

みんな質問がいくつかあります:

  1. switchステートメントとif...elseの間にJavaScriptのパフォーマンスの違いはありますか?
  2. もしそうなら、なぜですか?
  3. switchif...elseの動作はブラウザ間で異なりますか? (FireFox、IE、Chrome、Opera、Safari)

この質問をする理由は、Firefoxでswitchステートメントのパフォーマンスが約1000のケースで向上しているように見えるためです。


編集済み残念ながら、これは私のコードではありません。Javascriptはコンパイルされたライブラリからサーバーサイドで作成されており、コードにアクセスできません。 JavaScriptを生成しているメソッドが呼び出されます

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvaluesはコンマ区切りのリストです。

それが作り出すものは

function [name] (value) {
  if (value == [value from array index x]) {
     [action from array index x]
  }
}

注:ここで、[name] =サーバーサイド関数に渡される名前

ここで、関数の出力をTextAreaに挿入するように変更し、関数を解析するJavaScriptコードを記述して、caseステートメントのセットに変換しました。

最後に、この関数を実行すると正常に実行されますが、IEとFirefoxではパフォーマンスが異なります。

126
John Hartsock

一般的な回答:

  1. はい、通常。
  2. 詳細はこちら
  3. はい、それぞれに異なるJS処理エンジンがあるため、下のサイトでテストを実行する際、スイッチは多数の反復でif、elseifを常に実行しました。

テストサイト

99
Tommy

どちらも使用しないほうがよい場合もあります。たとえば、「ディスパッチ」の状況では、Javascriptを使用するとまったく異なる方法で処理できます。

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

オブジェクトを作成して多方向分岐を設定すると、多くの利点があります。機能を動的に追加および削除できます。データからディスパッチテーブルを作成できます。プログラムで調べることができます。他の関数を使用してハンドラーを構築できます。

「ケース」に相当する関数呼び出しのオーバーヘッドが追加されますが、特定のキーの関数を見つけるためのハッシュルックアップの利点(多くの場合)。

58
Pointy

switchif...else if...elseのパフォーマンスの違いは小さく、基本的に同じ動作をします。違いを生む可能性のある1つの違いは、テストする式がswitchで1回しか評価されず、各ifに対して評価されることです。式を評価するのにコストがかかる場合、1回実行する方が100回実行するよりももちろん高速です。

これらのコマンド(およびすべてのスクリプト全般)の実装の違いは、ブラウザーによってかなり異なります。異なるブラウザで同じコードを使用した場合、かなり大きなパフォーマンスの違いが見られることがよくあります。

すべてのブラウザですべてのコードのパフォーマンスをテストすることはほとんどできないため、実行中の作業に最適なコードを選択し、実行方法を最適化するのではなく、実行する作業量を減らしてください。

17
Guffa

構文以外に、スイッチはO(log n)にするツリーを使用して実装できますが、if/elseO(n)手続き型アプローチで実装する必要があります。多くの場合、それらは両方とも手続き的に処理され、唯一の違いは構文です。さらに、if/elseの10kケースを静的に入力しない限り、それは本当に重要ですか?

6
Evan Carroll
  1. 違いがある場合、気付くほど大きくなることはありません。
  2. なし
  3. いいえ、すべて同じように機能します。

基本的に、コードを最も読みやすくするものなら何でも使用してください。 1つまたは他の構成要素がよりクリーンで読みやすく保守しやすい場所になることは間違いありません。これは、おそらくJavaScriptコードで数ナノ秒を節約するよりもはるかに重要です。

6
Jon Benedicto

Pointy's answer は、switchまたはif/elseの代替としてオブジェクトリテラルの使用を提案します。私もこのアプローチが好きですが、答えのコードはmap関数が呼び出されるたびに新しいdispatchオブジェクトを作成します。

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

mapに多数のエントリが含まれている場合、これにより大きなオーバーヘッドが発生する可能性があります。アクションマップを1回だけ設定し、そのたびに作成済みのマップを使用することをお勧めします。次に例を示します。

var actions = {
    'explode': function() {
        prepExplosive();
        if( flammable() ) issueWarning();
        doExplode();
    },

    'hibernate': function() {
        if( status() == 'sleeping' ) return;
        // ... I can't keep making this stuff up
    },
    // ...
};

function dispatch( name ) {
    var action = actions[name];
    if( action ) action();
}
3
Michael Geary

Switch文とif ... else if .... elseの間にJavaScriptのパフォーマンスの違いはありますか?

switchは、複数のif-else状態を防ぎたい場合に便利/短いとは思いません。

Switchとif ... else if ... elseの動作はブラウザによって異なりますか? (FireFox、IE、Chrome、Opera、Safari)

動作はすべてのブラウザで同じです:)

3
Sarfraz

If-elseが一般的にスイッチよりも速い場合、

http://jsperf.com/switch-if-else/46

1
sidonaldson
  1. ワークベンチは、場合によっては非常に小さな違いをもたらす可能性がありますが、処理方法はブラウザに依存するため、気にする価値はありません
  2. 処理方法が異なるため
  3. とにかく動作が異なる場合は、ブラウザと呼ぶことはできません
1
Koen