Les instructions Switch sont généralement plus rapides que les instructions if-else-if équivalentes (comme par exemple décrites dans cet article ) en raison des optimisations du compilateur.
Comment cette optimisation fonctionne-t-elle réellement? Quelqu'un at-il une bonne explication?
c#
performance
switch-statement
if-statement
Dirk Vollmar
la source
la source
Réponses:
Le compilateur peut créer des tables de saut le cas échéant. Par exemple, lorsque vous utilisez le réflecteur pour regarder le code produit, vous verrez que pour les gros commutateurs sur les chaînes, le compilateur générera en fait du code qui utilise une table de hachage pour les distribuer. La table de hachage utilise les chaînes comme clés et les délègue aux
case
codes comme valeurs.Cela a un meilleur temps d'exécution asymptotique que beaucoup de
if
tests chaînés et est en fait plus rapide même pour relativement peu de chaînes.la source
Il s'agit d'une légère simplification, car généralement tout compilateur moderne qui rencontre une
if..else if ..
séquence qui pourrait être convertie de manière triviale en une instruction switch par une personne, le compilateur le fera également. Mais juste pour ajouter plus de plaisir, le compilateur n'est pas limité par la syntaxe et peut donc générer en interne des instructions de type "switch" qui ont un mélange de plages, de cibles uniques, etc. - et ils peuvent (et font) le faire à la fois pour switch et if. instructions .else.Quoi qu'il en soit, une extension de la réponse de Konrad est que le compilateur peut générer une table de saut, mais ce n'est pas nécessairement garanti (ni souhaitable). Pour diverses raisons, les tables de saut font de mauvaises choses aux prédicteurs de branche sur les processeurs modernes, et les tables elles-mêmes font de mauvaises choses pour mettre en cache le comportement, par exemple.
Si un compilateur générait réellement une table de saut pour cela, il serait probablement plus lent que le
if..else if..
code de style alternatif à cause de la table de saut qui annule la prédiction de branche.la source
Les statistiques sans match peuvent ne pas être bonnes.
Si vous téléchargez réellement la source, les valeurs sans correspondance sont connues pour être 21, à la fois dans le cas if et switch. Un compilateur doit être capable d'abstraction, sachant quelle instruction doit être exécutée à tout moment, et un processeur doit être capable de prédire correctement les branches.
Le cas le plus intéressant est celui où tous les cas ne se cassent pas, à mon avis, mais cela n'a peut-être pas été la portée de l'expérience.
la source
Les instructions switch / case peuvent être généralement plus rapides à 1 niveau, mais lorsque vous commencez à entrer dans 2 ou plus, les instructions switch / case commencent à prendre 2-3 fois plus longtemps que les instructions if / else imbriquées.
Cet article propose des comparaisons de vitesse mettant en évidence les différences de vitesse lorsque de telles instructions sont imbriquées.
Par exemple, selon leurs tests, un exemple de code comme celui-ci:
terminé en deux fois moins que l'instruction switch / case équivalente a pris pour s'exécuter:
Oui, c'est un exemple rudimentaire, mais cela illustre ce point.
Donc, une conclusion pourrait être d'utiliser switch / case pour des types simples qui ne sont qu'un niveau de profondeur, mais pour des comparaisons plus complexes et plusieurs niveaux imbriqués, utilisez les constructions classiques if / else?
la source
Le seul avantage du cas if est lorsqu'il y a une augmentation notable de la fréquence d'occurrence du premier cas.
Je ne sais pas exactement où se trouve le seuil, mais j'utilise la syntaxe de cas à moins que le premier "presque toujours" passe le premier test.
la source