La JVM actuelle possède deux types de codes d'octets de commutation : LookupSwitch et TableSwitch.
Chaque cas dans une instruction switch a un décalage entier, si ces décalages sont contigus (ou presque contigus sans grands écarts) (cas 0 : cas 1 : cas 2, etc.), alors TableSwitch est utilisé.
Si les décalages sont dispersés avec de grands écarts (cas 0 : cas 400 : cas 93748 :, etc.), alors LookupSwitch est utilisé.
La différence, en bref, est que TableSwitch se fait en temps constant car chaque valeur dans la plage de valeurs possibles se voit attribuer un décalage de code d'octets spécifique. Ainsi, lorsque vous donnez à l'instruction un décalage de 3, elle sait à quelle branche correcte sauter.
LookupSwitch utilise une recherche binaire pour trouver la bonne branche de code. Cela s'exécute en temps O(log n), ce qui est toujours bien, mais ce n'est pas le meilleur.
Pour plus d'informations à ce sujet, consultez ici : Différence entre LookupSwitch et TableSwitch de la JVM ?
Donc en ce qui concerne celui qui est le plus rapide, utilisez cette approche : Si vous avez 3 cas ou plus dont les valeurs sont consécutives ou presque consécutives, utilisez toujours un switch.
Si vous avez 2 cas, utilisez une instruction if.
Pour toute autre situation, switch est probablement plus rapide, mais ce n'est pas garanti, car la recherche binaire dans LookupSwitch pourrait rencontrer un scénario défavorable.
Gardez également à l’esprit que la JVM exécutera des optimisations JIT sur les instructions if qui tenteront de placer la branche la plus utilisée en premier dans le code. Cela s'appelle la "Prédiction de branche". Pour plus d'informations à ce sujet, consultez ici : https://dzone.com/articles/branch-prediction-in-java
Vos expériences peuvent varier. Je ne sais pas si la JVM n'exécute pas une optimisation similaire sur LookupSwitch, mais j'ai appris à faire confiance aux optimisations JIT et à ne pas essayer d'anticiper le compilateur.
0 votes
Peut-être que c'est aussi une réponse pour Java : stackoverflow.com/questions/767821/…
20 votes
En général, de Wikipédia: Si la plage des valeurs d'entrée est identifiablement 'faible' et comporte seulement quelques lacunes, certains compilateurs qui intègrent un optimiseur peuvent en réalité implémenter l'instruction switch comme une table de branches ou un tableau de pointeurs de fonctions indexés au lieu d'une longue série d'instructions conditionnelles. Cela permet à l'instruction switch de déterminer instantanément quelle branche exécuter sans avoir à parcourir une liste de comparaisons.
0 votes
La meilleure réponse à cette question l'explique très bien. Cet article explique également très bien tout.
0 votes
Je souhaiterais que dans la plupart des cas, un compilateur d'optimisation soit capable de générer un code ayant des caractéristiques de performance similaires. En tout cas, il faudrait appeler des millions de fois pour remarquer une quelconque différence.
0 votes
@Tobiask les deux questions sont différentes.
0 votes
Comme la réponse suggère que pour le commutateur il utilise HashMap alors c'est certainement plus rapide mais utilise une mémoire supplémentaire, ce qui dans ce cas de figure, si vous n'utilisez pas de mémoire supplémentaire.
0 votes
@Deepakkk : En fait... ils ne le sont pas. Et la réponse donne une explication pour laquelle
switch
est plus rapide en général.0 votes
@Mitch Wheat : Non, ce n'est pas le cas. Je viens de le tester. Il se pourrait cependant qu'une certaine optimisation se produise à l'exécution par le JIT, mais je ne peux pas le prouver.
0 votes
@Felix Kling: la réponse suggère que si un commutateur contient plus de cinq éléments, il est implémenté en utilisant une table de recherche ou une liste de hachage. Mais si le commutateur contient un seul élément comme je l'ai mentionné dans l'exemple
0 votes
@Max : J'ai dit des performances similaires, PAS le même code. Avez-vous fait un test de performance ?
0 votes
@Deepakkk : Peut-être devriez-vous spécifier explicitement que vous n'êtes intéressé que par le cas avec un élément. Vous savez, nous généralisons /abstrayons normalement les problèmes. Bien que j'aie tendance à dire que dans ce cas spécifique, vous ne trouverez aucune différence de performance.
0 votes
@Felix Kling. Merci. Votre réponse est vraiment utile pour moi.
2 votes
Vous devez vous méfier des livres qui font des déclarations comme celle-ci sans explication/preuve/raisonnement.
0 votes
Possible duplicate de Quelle est la différence de performance relative entre une déclaration if/else et une déclaration switch en Java ?
0 votes
Possible duplicate de Y at-il une différence significative entre l'utilisation de if/else et de switch-case en C# ?