JavaScriptスイッチとif…else if…else


143

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

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

この質問をする理由はswitch、Firefoxで約1000ケースのステートメントを使用すると、パフォーマンスが向上するようです。


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

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

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

それが生み出すものは

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

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

次に、TextAreaに挿入されるように関数の出力を変更し、関数を解析するためのJavaScriptコードをいくつかcase記述し、それを一連のステートメントに変換しました。

最後に、関数を実行すると問題なく動作しますが、IEとFirefoxではパフォーマンスが異なります。


1
何が最適かを調べるためのコードサンプルを提案します。つまり、あなたがこれを尋ねる理由があるはずですよね?
jcolebrand

私の長い経験では、100ケースのswitchステートメントまたは100パートのif / elseシリーズが良いアイデアであると言えるケースはほとんどないので、現在の状況を投稿してください。
先のとがった

申し訳ありませんが、数百の条件ではなく数千の条件
ジョンハートソック2010年

2
皆さん、ご意見ありがとうございます。しかし、私の問題は実際にはif文とswith文の違いではありませんでした。これは、ステートメント内で実行されるコードでした。あなたの助けのためにあなたのすべてに+1します。ご不便をおかけして申し訳ありません。時には、解決策を見つけるために他の人と物事を話し合う必要があるだけです。
John Hartsock、

回答:


113

一般的な答え:

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

テストサイト


1
:あなたはどの条件文を使用する際のTLDRたい場合はこちらの記事内のセグメントへの直接リンクは、そのアドレス指定のあるoreilly.com/server-administration/excerpts/even-faster-websites/...は
edhedges

2
@トミー良い記事、共有してくれてありがとう。ただし、この記事では、JSのステートメントswitchとのif/thenステートメントのパフォーマンスにはほとんど差がないと述べています。記事では、これはまだらなswitch最適化と、さまざまなJSエンジンのさまざまな機能が原因であると述べています。引用:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
Jasper

3
この説明に数値化できるものはありますか?それは多くの「ベストプラクティス/時期尚早の最適化」予想のように読みます。これも7年前に書かれたため、この時期にJavaScriptの最適化が大幅に変更されました。コンパイルされた言語では、これら3つの操作のパフォーマンスの違いは、「ほとんど気にするほど重要ではありません」。実際のパフォーマンスに影響を与えない最適化を気にしないでください。読みやすさを最適化します。
Thomson Comer 2016

3
@Tommy« 詳細はこちら »は404を示していますが、何がありましたか?
LogicDaemon

2
@LogicDaemon-IIRCはいくつかのoRiellyテキストボックスへのリンクであり、いくつかの詳細なJSパフォーマンスの考慮事項/ディスカッションに入りました
Tommy

61

どちらも使用しない方がよい場合もあります。たとえば、「ディスパッチ」の状況では、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();
}

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

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


2
あなたの戦略は良く、私はそれを頻繁に使用しています。ただし、@ Michael Gearyで指摘されているように、stackoverflow.com / a / 45336805/5936119のように、マップ変数はディスパッチコンテキストの外部で宣言する必要があります。そうしないと、常に再評価されます。
Daniel Santana

@DanielSantanaは本当ですが、それがかなり高いとは思えません。特に、関数が最初に解析されると、テキストは静的であるため、コード自体を再生成する必要はありません。
Pointy

18

a switchとのパフォーマンスの差if...else if...elseは小さく、基本的に同じ作業を行います。違いをもたらす可能性のあるそれらの1つの違いは、テストする式はswitch、各について評価される間、たまにしか評価されないことifです。式を評価するのにコストがかかる場合、1回行う方が100回行うよりも高速です。

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

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


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

基本的に、コードを最も読みやすくするものを使用します。1つまたは他の構成要素がよりクリーンで読みやすく、保守しやすい場所が確実にあります。これは、JavaScriptコードで数ナノ秒を節約するよりもはるかに重要です。


5
特にJavaScriptで、意味と読みやすさ(したがって、保守性)切り札は、任意の間のパフォーマンスの違いをローカライズif..elseし、switch独自のブラウザのバージョンコンピュータのハードウェアとOSの組み合わせによって引き起こされます。
jball

2
同意するかどうかはわかりませんが、たとえば、大規模なデータベース、ツリーのトラバースなどのループで使用すると、実際に気付く可能性があります
ghoppe

2
私は間違いなくそう思います。Webアプリケーションがますます複雑になるにつれて、この違いはアプリケーションにとって重要であり、ブラウザーに応じて変化する可能性があります。
joshvermaire

7
重要なことは、クリーンで保守可能なコードを書くことです。パフォーマンスの問題が発生した場合-プロファイル。次に、修正するコードを決定します。想定されるパフォーマンスの問題で保守性を犠牲にしないでください。
Jon Benedicto

3
「if else if else ...」はO(n)、「switch」はO(1)またはO(log(n))のいずれかです。どのようにして違いが十分に大きくなることはあり得ないと正直に述べることができますか?100万件のケースが切り替わり(コードが生成されれば簡単に可能です)、控えめに言っても間違いなく気付くでしょう。
dragonroot

6

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


7年後...定数の数値の場合を除いて、ツリーの実装がどのように可能であるかはわかりません)。
Ed Staub、2017

4

Pointyの回答は、switchor if/の代わりにオブジェクトリテラルを使用することを示唆していますelse。私もこのアプローチが好きですがmapdispatch関数が呼び出されるたびに、回答のコードが新しいオブジェクトを作成します。

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

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

私はそうは思わない、switchあなたが複数のif-else条件を防ぎたいなら、便利/短いです。

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

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


5
switch is useful/short if you want prevent multiple if-else conditions.はい、ありがとうございます。
NiCkニューマン2015

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.