Si vs passer en Vitesse
Instructions de commutation sont généralement plus rapide que l'équivalent if-else-if (tel que par exemple décrit dans ce l'article) grâce à des optimisations du compilateur.
Comment cette optimisation fait travailler? Quelqu'un aurait-il une bonne explication?
Explique: stackoverflow.com/questions/395618/if-else-vs-switch
Une possible bonne réponse: dotnetperls.com/if-switch-performance
Une possible bonne réponse: dotnetperls.com/if-switch-performance
OriginalL'auteur Dirk Vollmar | 2009-01-14
Vous devez vous connecter pour publier un commentaire.
Le compilateur peut construire sauter les tables, le cas échéant. Par exemple, lorsque vous utilisez le réflecteur de regarder le code généré, vous verrez que pour les énormes commutateurs sur les cordes, le compilateur va en fait générer du code qui utilise une table de hachage pour l'expédition de ces. La table de hachage utilise les chaînes de caractères comme des clés et des délégués à la
case
codes de valeurs.Cela a asymptotique meilleure exécution que beaucoup de enchaînés
if
essais et il est effectivement plus rapide, même pour relativement peu de chaînes.Ils ont également convertir à l'arbre des comparaisons dans certains cas. Le raisonnement est un peu complexe mais en gros se résume à la table d'indirection de la stérilisation moderne cpu jump cible tampons et donc efface la direction de la variable explicative. J'ai vaguement souvenir d'un papier à la GCC de la conférence sur codegen pour les interrupteurs.
Que signifie: interrupteur (a) cas "x": le cas de "y": le cas de "z": //break; } est plus rapide que: si(a=="x"||a=="b"||a=="c") //quelque chose de bien?
ici, nous n'avons pas imbriquée si ça, OU alors, qu'en pensez-vous?
Sur les anciens compilateurs potentiellement oui (mais notez que le nombre de cas est si petit qu'il ne pourrait pas faire une différence!). Les compilateurs modernes de faire beaucoup plus d'analyse de code. En conséquence, ils pourraient comprendre que ces deux extraits de code sont équivalentes, et d'appliquer les mêmes optimisations. Mais ce n'est que pure spéculation de ma part, je ne sais pas si tout le compilateur ne fait que.
OriginalL'auteur Konrad Rudolph
Konrad est correct. Dans le cas de la commutation sur contiguë gammes de nombres entiers (par exemple, lorsque vous avez affaire à 0, le cas 1, cas 2 cas .. n), le compilateur peut faire quelque chose d'encore mieux parce qu'il n'a même pas besoin de construire une table de hachage; il enregistre simplement un tableau de pointeurs de fonction, et peut donc charger son saut de la cible en temps constant.
OriginalL'auteur Crashworks
C'est une légère simplification typiquement moderne compilateur rencontre un
if..else if ..
séquence qui pourrait trivialement être converti en une instruction switch par une personne, le compilateur. Mais juste pour ajouter plus de plaisir que le compilateur n'est pas restreint par la syntaxe peut donc générer des "switch" comme des déclarations à l'interne qui ont un mélange de plages, des cibles uniques, etc-et ils peuvent (et vont) faire cela pour les deux switch et if..else.Anyhoo, une extension à Konrad réponse est que le compilateur peut générer un saut de la table, mais ce n'est pas nécessairement garanti (ni souhaitable). Pour une variété de raisons de sauter tables de faire de mauvaises choses à la direction des prédicteurs sur les processeurs modernes, et les tableaux se faire de mauvaises choses pour le cache de comportement, par exemple.
Si un compilateur effectivement généré un saut de la table, pour cela, il serait probablement plus lent que l'autre
if..else if..
code de style en raison de la sauter table de vaincre direction de la prévision.OriginalL'auteur olliej
Comme Konrad dit, le compilateur peut construire une table de Saut.
En C++ une raison, il peut est en raison de la limitation de commutateurs.
OriginalL'auteur J.J.
Le non-match, les stats ne peut pas être bon.
Si vous avez réellement télécharger le code source, le pas de match valeurs sont connus pour être le 21, dans les deux cas et le commutateur de cas. Un compilateur doit être en mesure de faire abstraction, sachant que l'instruction doit être exécutée à tout moment, et un PROCESSEUR doit être capable de direction de prédire correctement.
Le plus intéressant est quand pas tous les cas les pauses, à mon avis, mais qui peuvent ne pas avoir été la portée de l'expérience.
OriginalL'auteur Calyth
Switch/case déclarations peuvent être généralement plus rapide 1-niveau profond, mais lorsque vous commencez à recevoir dans 2 ou plus, switch/case déclarations de commencer à prendre 2 à 3 fois plus longtemps que imbriquée if/else.
Cet article a une vitesse de comparaisons mettant en évidence les différences de vitesse lorsque de telles déclarations sont imbriqués.
Par exemple, selon leurs tests, des exemples de code comme le suivant:
fini en la moitié le temps l'équivalent switch/case instruction nécessaire à l'exécution:
Oui, et c'est rudimentaire exemple, mais il illustre le point.
Si une conclusion peut-être utiliser le commutateur/cas pour les types simples ne comportent qu'un seul niveau de profondeur, mais pour les plus complexes les comparaisons et plusieurs niveaux imbriqués utiliser le classique si/d'autre constructions?
OriginalL'auteur Thrawn Wannabe
Le seul avantage de la si plus de cas, c'est quand il y a une augmentation notable de l'apparition de la fréquence de la première affaire.
Vous ne savez pas exactement où le seuil est, mais j'cas d'utilisation de la syntaxe de moins que le premier "presque toujours" passe le premier test.
OriginalL'auteur Ralph