web-dev-qa-db-fra.com

Commutateur Javascript vs si… sinon si… autre

Les gars, j'ai quelques questions:

  1. Existe-t-il une différence de performances en JavaScript entre une instruction switch et un if...else?
  2. Si oui, pourquoi?
  3. Le comportement de switch et if...else différents sur les navigateurs? (FireFox, IE, Chrome, Opera, Safari)

La raison de cette question est que j’obtiens de meilleures performances sur une instruction switch avec environ 1000 observations dans Firefox.


Édité Malheureusement, ce n'est pas mon code, le Javascript est produit à partir d'une bibliothèque compilée et je n'ai pas accès au code. La méthode qui produit le javascript s'appelle

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvalues est une liste séparée par des virgules.

ce qu'il produit est

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

Note: où [name] = le nom transmis à la fonction serverside

Maintenant, j'ai changé la sortie de la fonction pour l'insérer dans un TextArea, écrit du code JavaScript pour analyser la fonction et converti celui-ci en un ensemble d'instructions case.

enfin, je lance la fonction et elle fonctionne bien, mais les performances diffèrent dans IE et Firefox.

126
John Hartsock

Répondre en généralités:

  1. Oui d'habitude.
  2. Voir plus d'infos ici
  3. Oui, car chacun a un moteur de traitement JS différent. Cependant, lors de l'exécution d'un test sur le site ci-dessous, le commutateur effectue toujours la sortie de if, elseif sur un grand nombre d'itérations.

site de test

99
Tommy

Parfois, il vaut mieux ne pas utiliser ni l'un ni l'autre. Par exemple, dans une situation "d'envoi", Javascript vous permet de faire les choses d'une manière complètement différente:

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

La création de branches multiples en créant un objet présente de nombreux avantages. Vous pouvez ajouter et supprimer des fonctionnalités de manière dynamique. Vous pouvez créer la table de répartition à partir de données. Vous pouvez l'examiner par programmation. Vous pouvez construire les gestionnaires avec d'autres fonctions.

Il y a la surcharge ajoutée d'un appel de fonction pour obtenir l'équivalent d'un "cas", mais l'avantage (quand il y a beaucoup de cas) d'une recherche de hachage pour trouver la fonction d'une clé particulière.

58
Pointy

La différence de performance entre switch et if...else if...else est petit, ils font essentiellement le même travail. Une différence entre eux qui peut faire la différence est que l'expression à tester n'est évaluée qu'une fois dans un switch alors qu'elle est évaluée pour chaque if. S'il est coûteux d'évaluer l'expression, le faire une fois est bien sûr plus rapide que le faire cent fois.

La différence dans la mise en œuvre de ces commandes (et de tous les scripts en général) diffère un peu d'un navigateur à l'autre. Il est courant de voir d’importantes différences de performances pour le même code dans différents navigateurs.

Comme vous pouvez difficilement tester tous les codes de performance dans tous les navigateurs, vous devez choisir le code qui convient le mieux à votre activité et essayer de réduire la quantité de travail effectué plutôt que d'optimiser sa réalisation.

17
Guffa

Autre que la syntaxe, un commutateur peut être implémenté à l'aide d'un arbre qui le rend O(log n), alors qu'un si/autre doit être implémenté avec une approche procédurale O(n) . Le plus souvent, ils sont tous deux traités de manière procédurale et la seule différence est la syntaxe. De plus, est-ce vraiment important - à moins de taper statiquement 10k cas de if/else de toute façon?

6
Evan Carroll
  1. S'il y a une différence, elle ne sera jamais assez grande pour être remarquée.
  2. N/A
  3. Non, ils fonctionnent tous de manière identique.

Fondamentalement, utilisez ce qui rend le code le plus lisible. Il existe bien des endroits où l’une ou l’autre construction permet d’être plus propre, plus lisible et plus facile à entretenir. Ceci est bien plus important que peut-être économiser quelques nanosecondes en code JavaScript.

6
Jon Benedicto

La réponse de Pointy suggère l'utilisation d'un littéral d'objet comme alternative à switch ou if/else. J'aime aussi cette approche, mais le code de la réponse crée un nouvel objet map chaque fois que la fonction dispatch est appelée:

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

Si map contient un grand nombre d'entrées, cela peut entraîner une surcharge importante. Il est préférable de configurer la carte d'action une seule fois, puis d'utiliser à chaque fois la carte déjà créée, par exemple:

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

Existe-t-il une différence de performance en Javascript entre une instruction switch et un if ... else si .... else?

Je ne pense pas, switch est utile/bref si vous voulez éviter plusieurs if-else conditions.

Le comportement de switch et si ... sinon si ... sinon est-il différent d'un navigateur à l'autre? (FireFox, IE, Chrome, Opera, Safari)

Le comportement est le même sur tous les navigateurs :)

3
Sarfraz

Il s'avère que si-sinon si généralement plus rapide que le commutateur

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

1
sidonaldson
  1. Le workbenching peut entraîner de très petites différences dans certains cas, mais la méthode de traitement dépend de toute façon du navigateur, il est donc inutile de s’ennuyer.
  2. En raison de différentes méthodes de traitement
  3. Vous ne pouvez pas appeler cela un navigateur si le comportement serait de toute façon différent
1
Koen