Javascript-Schalter vs. wenn ... sonst wenn ... sonst

143

Leute, ich habe ein paar Fragen:

  1. Gibt es in JavaScript einen Leistungsunterschied zwischen einer switchAnweisung und einer if...else?
  2. Wenn ja warum?
  3. Ist das Verhalten switchund if...elseandere in allen Browsern? (FireFox, IE, Chrome, Opera, Safari)

Der Grund für diese Frage ist, dass ich bei einer switchAussage mit ca. 1000 Fällen in Firefox anscheinend eine bessere Leistung erhalte .


Bearbeitet Leider ist dies nicht mein Code. Das Javascript wird serverseitig aus einer kompilierten Bibliothek erstellt und ich habe keinen Zugriff auf den Code. Die Methode, mit der das Javascript erstellt wird, wird aufgerufen

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvaluesist eine durch Kommas getrennte Liste.

was es produziert ist

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

Hinweis: Dabei wird [name]der Name an die serverseitige Funktion übergeben

Jetzt habe ich die Ausgabe der Funktion, die in eine TextArea eingefügt werden soll, geändert, JavaScript-Code geschrieben, um die Funktion zu analysieren, und ihn in eine Reihe von caseAnweisungen konvertiert .

Schließlich starte ich die Funktion und sie läuft gut, aber die Leistung unterscheidet sich in IE und Firefox.

John Hartsock
quelle
1
Ich würde ein Codebeispiel vorschlagen, um zu untersuchen, was optimal ist. Ich meine, es muss einen Grund geben, warum du das fragst, oder?
Jcolebrand
Bitte posten Sie, was Sie vorhaben, da es nach meiner langjährigen Erfahrung nur sehr wenige Fälle gibt, für die ich eine 100-Fall-Switch-Anweisung oder eine 100-teilige if / else-Serie als gute Idee bezeichnen würde.
Pointy
Entschuldigung Jungs, nicht 100er, sondern Tausende von Bedingungen
John Hartsock
2
Vielen Dank für die Eingabe. Aber mein Problem war eigentlich nicht der Unterschied zwischen den if- und swith-Aussagen. Es war der Code, der in der Anweisung ausgeführt wurde. +1 an euch alle für eure Hilfe. Entschuldigen Sie die Unannehmlichkeiten. Manchmal müssen Sie nur mit einer anderen Person sprechen, um die Lösung zu finden.
John Hartsock

Antworten:

113

Allgemein antworten:

  1. Ja normalerweise.
  2. Weitere Informationen finden Sie hier
  3. Ja, da jede über eine andere JS-Verarbeitungs-Engine verfügt. Bei der Ausführung eines Tests auf der folgenden Site führte der Switch jedoch immer das if, elseif für eine große Anzahl von Iterationen aus.

Teststelle

Tommy
quelle
1
Wenn Sie eine TLDR wünschen, wann welche Bedingungen verwendet werden sollen, finden Sie hier einen direkten Link zu einem Segment im Artikel, in dem Folgendes
edhedges
2
@ Tommy Guter Artikel, danke fürs Teilen. Der Artikel besagt jedoch, dass es einen vernachlässigbaren Leistungsunterschied zwischen switchund if/thenAnweisungen in JS gibt. Der Artikel besagt, dass dies auf eine fleckige switchOptimierung und die unterschiedlichen Funktionsweisen verschiedener JS-Engines zurückzuführen ist. Zitat:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
Jasper
3
Ist in dieser Beschreibung etwas Quantifizierbares dargestellt? Es liest sich wie eine Menge "Best Practices / vorzeitige Optimierung" Vermutungen. Es wurde auch vor 7 Jahren geschrieben, daher haben sich die Javascript-Optimierungen in dieser Zeit enorm verändert. In kompilierten Sprachen ist der Leistungsunterschied zwischen diesen drei Operationen "fast nie signifikant genug, um sich darum zu kümmern". Machen Sie sich nicht die Mühe, Dinge zu optimieren, die die tatsächliche Leistung nicht beeinträchtigen. Optimieren Sie die Lesbarkeit.
Thomson Comer
3
@Tommy « Weitere Informationen hier sehen » gibt 404, was war da?
LogicDaemon
2
@LogicDaemon - IIRC ist ein Link zu einem oRielly-Textfeld, das in einige eingehende Überlegungen / Diskussionen zur JS-Leistung eingegangen ist
Tommy
61

Manchmal ist es besser, keine zu verwenden. In einer "Versandsituation" können Sie beispielsweise mit Javascript ganz andere Dinge tun:

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();
}

Das Einrichten einer Mehrwegverzweigung durch Erstellen eines Objekts bietet viele Vorteile. Sie können Funktionen dynamisch hinzufügen und entfernen. Sie können die Versandtabelle aus Daten erstellen. Sie können es programmgesteuert untersuchen. Sie können die Handler mit anderen Funktionen erstellen.

Es gibt den zusätzlichen Aufwand eines Funktionsaufrufs, um das Äquivalent eines "Falls" zu erhalten, aber den Vorteil (wenn es viele Fälle gibt) einer Hash-Suche, um die Funktion für einen bestimmten Schlüssel zu finden.

Spitze
quelle
2
Ihre Strategie ist gut und ich benutze sie oft. Wie von @Michael Geary stackoverflow.com/a/45336805/5936119 angegeben , muss die Kartenvariable jedoch außerhalb des Versandkontexts deklariert werden , da sie sonst immer neu bewertet wird.
Daniel Santana
@ DanielSantana stimmt, aber ich bezweifle, dass das sehr teuer ist. Insbesondere muss der Code selbst nach dem ersten Analysieren einer Funktion nicht neu generiert werden, da der Text statisch ist.
Pointy
18

Der Leistungsunterschied zwischen a switchund if...else if...elseist gering, sie machen im Grunde die gleiche Arbeit. Ein Unterschied zwischen ihnen, der einen Unterschied machen kann, besteht darin, dass der zu testende Ausdruck nur gelegentlich switchausgewertet wird if. Wenn es teuer ist, den Ausdruck zu bewerten, ist es natürlich schneller, ihn einmal zu machen, als ihn hundertmal zu machen.

Der Unterschied in der Implementierung dieser Befehle (und aller Skripte im Allgemeinen) unterscheidet sich zwischen den Browsern erheblich. In verschiedenen Browsern treten häufig große Leistungsunterschiede für denselben Code auf.

Da Sie kaum den gesamten Code in allen Browsern auf Leistung testen können, sollten Sie sich für den Code entscheiden, der am besten zu Ihrer Arbeit passt, und versuchen, den Arbeitsaufwand zu reduzieren, anstatt die Arbeitsweise zu optimieren.

Guffa
quelle
7
  1. Wenn es einen Unterschied gibt, wird er niemals groß genug sein, um bemerkt zu werden.
  2. N / A
  3. Nein, sie funktionieren alle identisch.

Verwenden Sie grundsätzlich alles, was den Code am besten lesbar macht. Es gibt definitiv Orte, an denen das eine oder andere Konstrukt sauberer, lesbarer und wartbarer ist. Dies ist weitaus wichtiger als das Speichern einiger Nanosekunden in JavaScript-Code.

Jon Benedicto
quelle
5
Insbesondere in Javascript übertreffen die Semantik und Lesbarkeit (und damit die Wartbarkeit) alle lokalisierten Leistungsunterschiede zwischen einer Kombination aus Computerhardware und Betriebssystem einer einzigartigen Browserversion if..elseund werden switchdurch diese verursacht.
Jball
2
Ich weiß nicht, ob ich damit einverstanden bin, es könnte tatsächlich bemerkt werden, wenn es in einer Schleife mit beispielsweise einer großen Datenbank verwendet wird, die einen Baum durchquert usw.
Ghoppe
2
Ich bin definitiv anderer Meinung. Da Webanwendungen immer komplexer werden, kann dieser Unterschied für die Anwendung erheblich sein und sich je nach Browser ändern.
Joshvermaire
7
Das Wichtigste ist, sauberen, wartbaren Code zu schreiben. Wenn ein Leistungsproblem auftritt - Profil. Bestimmen Sie dann, welcher Code behoben werden soll. Verzichten Sie nicht auf Wartbarkeit für angenommene Leistungsprobleme.
Jon Benedicto
3
'if else if else ...' ist O (n), während 'switch' entweder O (1) oder O (log (n)) ist. Wie können Sie ehrlich sagen, dass der Unterschied niemals groß genug sein kann? Haben Sie eine Million Fälle im Wechsel (leicht möglich, wenn der Code generiert wird) und Sie werden es auf jeden Fall bemerken, um es gelinde auszudrücken.
Drachenwurzel
6

Anders als die Syntax kann ein Switch mithilfe eines Baums implementiert werden, der ihn erstellt O(log n), während ein if / else mit einem O(n)prozeduralen Ansatz implementiert werden muss. Häufiger werden beide prozedural verarbeitet und der einzige Unterschied ist die Syntax. Darüber hinaus spielt es wirklich eine Rolle - es sei denn, Sie geben statisch 10.000 Fälle von if / else ein?

Evan Carroll
quelle
7 Jahre später ... Ich sehe nicht, wie eine Baumimplementierung möglich ist, außer bei konstanten numerischen Fallwerten.
Ed Staub
4

Die Antwort von Pointy schlägt die Verwendung eines Objektliteral als Alternative zu switchoder if/ vor else. Ich mag diesen Ansatz auch, aber der Code in der Antwort erstellt mapjedes Mal ein neues Objekt, wenn die dispatchFunktion aufgerufen wird:

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();
}

Wenn mapeine große Anzahl von Einträgen enthalten ist, kann dies zu einem erheblichen Overhead führen. Es ist besser, die Aktionskarte nur einmal einzurichten und dann jedes Mal die bereits erstellte Karte zu verwenden, zum Beispiel:

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();
}
Michael Geary
quelle
3

Gibt es in Javascript einen Leistungsunterschied zwischen einer switch-Anweisung und einer if ... else if .... else?

Ich denke nicht, switchist nützlich / kurz, wenn Sie mehrere if-elseBedingungen verhindern wollen .

Ist das Verhalten des Wechsels und wenn ... sonst wenn ... sonst zwischen den Browsern unterschiedlich? (FireFox, IE, Chrome, Opera, Safari)

Das Verhalten ist in allen Browsern gleich :)

Sarfraz
quelle
5
switch is useful/short if you want prevent multiple if-else conditions.Ja, Sir, großartiger Beitrag.
NiCk Newman
1
  1. Workbenching kann in einigen Fällen zu sehr kleinen Unterschieden führen, aber die Art der Verarbeitung ist ohnehin browserabhängig, sodass es sich nicht lohnt, sich darum zu kümmern
  2. Wegen unterschiedlicher Verarbeitungsweisen
  3. Sie können es nicht als Browser bezeichnen, wenn das Verhalten sowieso anders wäre
Koen
quelle