259 votes

Y a-t-il une différence significative entre à l’aide d’if/else et switch-case en c# ?

Quel est l’avantage/inconvénient à utiliser une déclaration contre une en c#. Là, je ne peux imaginer qu’être grand de différence, sauf peut-être le look de votre code.

Y a-t-il une raison pourquoi la résultante IL ou les performances d’exécution associé serait radicalement différente ?

Associés : ce qui est plus rapide, mettre sur chaîne ou elseif type ?

396voto

ima Points 4782

Pour corriger sur "Scott Wisniewski' réponse (qui est mauvais sur tous les aspects, mais en quelque sorte obtenu upvoted et accepté)

Instruction SWITCH seul produit de la même assemblée que les Fi en debug ou en mode de compatibilité. Dans libération, il sera compilé dans saut de la table (par MSIL 'switch' instruction)- qui est O(1).

C# (contrairement à beaucoup d'autres langues) permet également de basculer sur les constantes de chaîne - et cela fonctionne un peu différemment. Il n'est évidemment pas pratique pour construire sauter les tables pour les chaînes de longueurs arbitraires, donc le plus souvent à la substitution seront compilées dans la pile de l'IFs.

Mais si le nombre de conditions est suffisante pour couvrir les frais généraux, le compilateur C# permettra de créer une table de hachage de l'objet, de le remplir avec des constantes de chaîne et de faire une recherche sur la table, suivi par sauter. Table de hachage de recherche n'est pas strictement O(1) et est perceptible à coûts constants, mais si le nombre de cas où des étiquettes est grand, il sera nettement plus rapide que de comparer à chaque constante de chaîne en IFs.

Pour résumer, si le nombre de conditions est de plus de 5 ou alors, préférez BASCULER, SI, sinon utiliser quelle que soit l'air mieux.

59voto

Scott Wisniewski Points 14420

En général (en tenant compte de toutes les langues et tous les compilateurs) une instruction switch PEUT PARFOIS être plus efficace que d'un if / else, car il est facile pour un compilateur pour générer sauter les tables à partir d'instructions de commutation. Il est possible de faire la même chose pour les if / else, compte tenu des contraintes appropriées, mais qui est beaucoup plus difficile.

Dans le cas de C#, c'est vrai aussi, mais pour d'autres raisons.

Avec un grand nombre de chaînes de caractères, il existe un important avantage de performance à l'aide d'une instruction switch, parce que le compilateur va utiliser une table de hachage pour mettre en œuvre le saut.

Avec un petit nombre de chaînes de caractères, les performances entre les deux est le même.

C'est parce que dans ce cas, le compilateur C# ne pas générer un saut de la table. Au lieu de cela, il génère MSIL qui est équivalent à if / ELSE blocs.

Il y a un "switch" instruction MSIL que lorsque jitted va utiliser un saut de la table pour mettre en œuvre une instruction switch. Il fonctionne uniquement avec les types integer, toutefois, cette question porte sur les chaînes de caractères).

Pour les petits nombres de chaînes, il est plus efficace pour le compilateur pour générer des SI / d'AUTRE blocs, puis il consiste à utiliser une table de hachage.

Quand j'ai d'abord remarqué, j'ai fait l'hypothèse que, parce que SI / d'AUTRE des blocs ont été utilisés avec un petit nombre de chaînes, que le compilateur n'a la même transformation pour un grand nombre de chaînes.

C'était FAUX. 'IMA' a eu la gentillesse de le signaler à moi (bien...il n'était pas du genre à ce sujet, mais il avait raison et j'avais tort, ce qui est l'essentiel)

J'ai aussi fait un abruti hypothèse sur l'absence d'un "switch" de l'enseignement en MSIL (j'ai pensé, si il y avait un interrupteur primitive, pourquoi n'ont-ils pas de l'utiliser avec une table de hachage, donc il ne doit pas être un interrupteur de primitives.... ). C'était à la fois tort et incroyablement stupide de ma part. Une fois de plus 'IMA' l'a souligné à moi.

J'ai fait les mises à jour ici parce que c'est la cote la plus élevée de poste, et l'on a accepté la réponse.

Cependant,je l'ai fait Wiki de la Communauté parce que je me dis que je ne mérite pas la REP pour le mal. Si vous obtenez une chance, veuillez jusqu'vote "ima"s post.

22voto

Will Points 76760

Le compilateur va optimiser à peu près tout dans le même code avec des différences mineures (Knuth, n’importe qui ?).

La différence est qu’une instruction switch est plus propre que quinze ans, si d’autre déclarations s’enchaînent.

Ne laissez pas amis amis pile instructions if-else.

19voto

Norman Ramsey Points 115730

Trois raisons de préférer l' switch:

  • Un compilateur de ciblage du code natif peut souvent compiler une instruction switch dans une branche conditionnelle plus indirecte sauter alors qu'une séquence de ifs nécessite une séquence de branches conditionnelles. En fonction de la densité de cas, un grand nombre de documents savants ont été écrits sur la façon de compiler les cas énoncés de manière efficace; certains d'entre eux sont de la lcc compilateur page. (Lcc était l'un des plus innovants de compilateurs pour les interrupteurs.)

  • Une instruction switch est un choix parmi les alternatives mutuellement exclusives et que le commutateur de la syntaxe qui rend ce flux de contrôle plus transparent pour le programmeur puis un nid de if-then-else.

  • Dans certaines langues, y compris certainement ML et Haskell, le compilateur vérifie pour voir si vous avez laissé de côté tout cas. Je considère que c'est l'un des principaux avantages de la ML et Haskell. Je ne sais pas si C# peuvent le faire.

Une anecdote: lors d'une conférence qu'il a donné sur la réception d'une récompense pour l'accomplissement d'une vie, j'ai entendu Tony Hoare dire que, de toutes les choses qu'il a fait dans sa carrière, il y avait trois qu'il était le plus fier:

  • Inventer Quicksort
  • En inventant l'instruction switch (Tony appelé l' case déclaration)
  • De début et de fin de sa carrière dans l'industrie

Je ne peux pas imaginer de vivre sans switch.

17voto

Kevin Points 57797

En fait, une instruction switch est plus efficace. Le compilateur optimise il à un look up table où avec if/else instructions cela est impossible. L’inconvénient est qu’une instruction switch ne peuvent pas servir avec les valeurs des variables.
Vous ne pouvez pas le faire :

il doit être

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X