En me souciant des performances de mon application Web, je me demande laquelle des instructions «if / else» ou switch est la meilleure en termes de performances?
123
En me souciant des performances de mon application Web, je me demande laquelle des instructions «if / else» ou switch est la meilleure en termes de performances?
if
etc.Réponses:
C'est la micro-optimisation et l'optimisation prématurée, qui sont mauvaises. Se soucier plutôt de la lisibilité et de la maintenabilité du code en question. S'il y a plus de deux
if/else
blocs collés ensemble ou si sa taille est imprévisible, alors vous pouvez fortement envisager uneswitch
déclaration.Alternativement, vous pouvez également récupérer Polymorphism . Commencez par créer une interface:
Et obtenez toutes les implémentations dans certains
Map
. Vous pouvez le faire de manière statique ou dynamique:Enfin, remplacez le
if/else
ouswitch
par quelque chose comme ceci (en laissant de côté les vérifications triviales comme les pointeurs nuls):Il est peut- être plus lent que
if/else
ouswitch
, mais le code est au moins beaucoup mieux maintenable.Lorsque vous parlez d'applications Web, vous pouvez utiliser
HttpServletRequest#getPathInfo()
comme clé d'action (éventuellement écrire un peu plus de code pour séparer la dernière partie de pathinfo en une boucle jusqu'à ce qu'une action soit trouvée). Vous pouvez trouver ici des réponses similaires:Si vous vous inquiétez des performances de l'application Web Java EE en général, cet article peut également vous être utile. Il existe d'autres domaines qui donnent un gain de performances beaucoup plus important que la seule (micro) optimisation du code Java brut.
la source
Je suis totalement d'accord avec l'opinion selon laquelle l'optimisation prématurée est quelque chose à éviter.
Mais il est vrai que la machine virtuelle Java a des bytecodes spéciaux qui pourraient être utilisés pour les switch ().
Voir WM Spec ( lookupswitch et tableswitch )
Il pourrait donc y avoir des gains de performances, si le code fait partie du graphique des performances du processeur.
la source
Il est extrêmement improbable qu'un if / else ou un commutateur soit la source de vos problèmes de performances. Si vous rencontrez des problèmes de performances, vous devez d'abord effectuer une analyse de profilage des performances pour déterminer où se trouvent les points lents. L'optimisation prématurée est la racine de tout Mal!
Néanmoins, il est possible de parler des performances relatives du commutateur par rapport à if / else avec les optimisations du compilateur Java. Notez d'abord qu'en Java, les instructions switch fonctionnent sur un domaine très limité - les entiers. En général, vous pouvez afficher une instruction switch comme suit:
où
c_0
,,c_1
... etc_N
sont des nombres entiers qui sont les cibles de l'instruction switch et<condition>
doivent se résoudre en une expression entière.Si cet ensemble est "dense" - c'est-à-dire (max (c i ) + 1 - min (c i )) / n> α, où 0 <k <α <1, où
k
est plus grand qu'une certaine valeur empirique, a une table de saut peut être générée, ce qui est très efficace.Si cet ensemble n'est pas très dense, mais n> = β, un arbre de recherche binaire peut trouver la cible dans O (2 * log (n)) qui est toujours aussi efficace.
Dans tous les autres cas, une instruction switch est exactement aussi efficace que la série équivalente d'instructions if / else. Les valeurs précises de α et β dépendent d'un certain nombre de facteurs et sont déterminées par le module d'optimisation de code du compilateur.
Enfin, bien sûr, si le domaine de
<condition>
n'est pas les nombres entiers, une instruction switch est complètement inutile.la source
Utilisez le commutateur!
Je déteste maintenir des blocs if-else! Faites un test:
Mon code standard C # pour l'analyse comparative
la source
switch
es loin?Je me souviens avoir lu qu'il existe 2 types d'instructions Switch dans le bytecode Java. (Je pense que c'était dans 'Java Performance Tuning' One est une implémentation très rapide qui utilise les valeurs entières de l'instruction switch pour connaître le décalage du code à exécuter. Cela nécessiterait que tous les entiers soient consécutifs et dans une plage bien définie Je suppose que l'utilisation de toutes les valeurs d'un Enum tomberait également dans cette catégorie.
Je suis cependant d'accord avec beaucoup d'autres affiches ... il est peut-être prématuré de s'inquiéter à ce sujet, à moins que ce ne soit du code très très chaud.
la source
switch
plusieurs manières différentes, certaines plus efficaces que d'autres. En général, l'efficacité ne sera pas pire qu'une simple «if
échelle», mais il y a suffisamment de variations (surtout avec le JITC) qu'il est difficile d'être beaucoup plus précis que cela.Selon Cliff Click dans son exposé sur Java One en 2009, un cours intensif sur le matériel moderne :
Vous pouvez obtenir ses diapositives complètes ici .
Cliff donne un exemple (finissant sur la diapositive 30) montrant que même avec le processeur effectuant un renommage de registre, une prédiction de branche et une exécution spéculative, il ne peut démarrer que 7 opérations en 4 cycles d'horloge avant d'avoir à bloquer en raison de deux échecs de cache qui prennent 300 cycles d'horloge pour revenir.
Donc, il dit que pour accélérer votre programme, vous ne devriez pas vous pencher sur ce genre de problème mineur, mais sur des problèmes plus importants tels que si vous effectuez des conversions de format de données inutiles, telles que la conversion de "SOAP → XML → DOM → SQL → ... "qui" passe toutes les données à travers le cache ".
la source
Dans mon test, la meilleure performance est ENUM> MAP> SWITCH> IF / ELSE IF dans Windows7.
la source
Time taken for String in Switch :3235 Time taken for String in if/else if :3143 Time taken for String in Map :4194 Time taken for String in ENUM :2866
Pour la plupart
switch
et la plupart desif-then-else
blocs, je ne peux pas imaginer qu'il existe des problèmes de performances appréciables ou significatifs.Mais voici le problème: si vous utilisez un
switch
bloc, son utilisation même suggère que vous basculez sur une valeur prise à partir d'un ensemble de constantes connues au moment de la compilation. Dans ce cas, vous ne devriez vraiment pas utiliser d'switch
instructions du tout si vous pouvez utiliser unenum
des méthodes spécifiques aux constantes.Par rapport à une
switch
instruction, une énumération fournit une meilleure sécurité de type et un code plus facile à gérer. Les énumérations peuvent être conçues de sorte que si une constante est ajoutée à l'ensemble de constantes, votre code ne se compilera pas sans fournir une méthode spécifique à la constante pour la nouvelle valeur. D'un autre côté, oublier d'ajouter un nouveaucase
à unswitch
bloc ne peut parfois être intercepté au moment de l'exécution que si vous avez la chance d'avoir configuré votre bloc pour lever une exception.Les performances entre
switch
et uneenum
méthode spécifique à une constante ne doivent pas être significativement différentes, mais cette dernière est plus lisible, plus sûre et plus facile à entretenir.la source