Pourquoi switch est plus rapide que si
Beaucoup de Java livres décrivent la switch
déclaration comme étant plus rapide que la if else
déclaration. Mais je n'ai pas trouver n'importe où pourquoi switch est plus rapide que si.
Exemple
J'ai une situation que je dois choisir un point quelconque de deux. Je peux utiliser soit utiliser
switch (item) {
case BREAD:
//eat Bread
break;
default:
//leave the restaurant
}
ou
if (item == BREAD) {
//eat Bread
} else {
//leave the restaurant
}
à l'examen du point et du PAIN est une constante de type int valeur.
Dans l'exemple ci-dessus qui est plus rapide dans l'action, et pourquoi?
- C'est peut-être une réponse aussi pour java: stackoverflow.com/questions/767821/...
- En général, à partir de Wikipédia: Si la plage de valeurs d'entrée est indéniablement "petits" et a seulement quelques lacunes, certains compilateurs qui intègrent un optimiseur peut effectivement mettre en œuvre l'instruction switch comme une branche de la table ou un tableau de indexés pointeurs de fonction au lieu d'une longue série d'instructions conditionnelles. Cela permet à l'instruction switch pour déterminer instantanément la branche à exécuter sans avoir à passer par une liste de comparaisons.
- La top réponse à cette question explique assez bien. Ce article explique tout très bien aussi.
- J'espère que dans la plupart des cas, une optimisation du compilateur serait capable de générer du code qui avait similaire caractéristiques de performance. Dans tous les cas, vous devez appeler plusieurs millions de fois à remarquer la différence.
- les deux questiona sont différents.
- comme la réponse suggère que, pour que l'interrupteur on utilise la table de hachage, alors il est sûrement plus rapide, mais utilise additionial de la mémoire, qui, en si ensuite le cas où vous n'utilisez pas toute la mémoire supplémentaire.
- En fait.... ils ne le sont pas. Et la réponse donne une explication pour pourquoi
switch
est plus rapide en général. - Blé: Il n'en a pas. Je viens de le tester. Il pourrait être bien que certains d'optimisation se fait au moment de l'exécution par JIT, mais ne peut pas prouver que.
- Kling : la réponse suggère que Si un commutateur contient plus de cinq articles, il est mis en œuvre à l'aide d'une table ou d'un hachage de la liste. Mais si l'interrupteur contient 1 élément comme je l'ai indiqué dans l'exemple
- Je l'ai dit similaire pour la performance, PAS le même code. Avez-vous référence?
- Peut-être que vous devriez mentionner explicitement que vous êtes seulement intéressé dans le cas d'un seul élément. Vous le savez, nous avons l'habitude de généraliser/problèmes abstraits. Même si j'ai tendance à dire que dans ce cas précis, vous ne trouverez pas de différences de performances.
- Kling. Merci Vraiment de votre réponse est utile pour moi.
- Il faut se méfier de livres que de faire des déclarations comme ça, sans explication/preuve/raisonnement.
- double possible de qu'est-Ce que la performance relative de la différence de if/else rapport de l'instruction switch en Java?
- Double Possible de Est-il une différence significative entre l'utilisation de if/else et switch-case en C#?
Vous devez vous connecter pour publier un commentaire.
Parce qu'il y a de spécial bytecode qui permettent d'instruction switch d'évaluation lorsqu'il y a un grand nombre de cas.
Si elle est réalisée, SI-les déclarations que vous auriez un chèque, d'un saut pour le prochain article, d'un chèque, d'un saut à la clause qui suit et ainsi de suite. Avec interrupteur de la JVM charge la valeur de comparer et parcourt le tableau de valeurs de trouver un match, ce qui est plus rapide dans la plupart des cas.
switch
ne peuvent pas être traduites dans untableswitch
bytecode de l'instruction, il peut devenir unlookupswitch
de l'instruction qui effectue la même façon un if/else (ii) untableswitch
instructions bytecode peut être compilé dans une série de if/else par le JIT, en fonction de facteurs tels que le nombre decase
s.tableswitch
vsloopuswitch
: stackoverflow.com/questions/10287700/...Un
switch
déclaration n'est pas toujours plus rapide qu'unif
déclaration. Il évolue mieux qu'une longue liste deif-else
étatsswitch
pouvez effectuer une recherche basée sur toutes les valeurs. Cependant, pour une courte condition qu'il ne soit pas plus rapide et peut être plus lente.switch
serait plus clair si pas plus rapide.Le courant de la JVM a deux types de commutateur d'octets de codes: LookupSwitch et TableSwitch.
Chaque cas dans une instruction switch a un nombre entier de décalage, si ces décalages sont contigus (ou presque contigus, sans grandes lacunes) (cas 0: cas 1: cas 2, etc.), puis TableSwitch est utilisé.
Si les décalages sont étalées avec de grandes lacunes (cas 0: 400 cas: cas 93748:, etc.), puis 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 est donnée spécifique byte-code de l'offset. Ainsi, lorsque vous donnez l'énoncé d'un décalage de 3, il sait à l'avance 3 à trouver la bonne direction.
De recherche commutateur utilise un binaire de recherche pour trouver le bon code de la branche. Cela s'exécute en O(log n) le temps, ce qui est encore bon, mais pas le meilleur.
Pour plus d'informations sur cette question, voir ici: La différence entre la JVM du LookupSwitch et TableSwitch?
Donc lequel est le plus rapide, l'utilisation de cette approche:
Si vous avez 3 ou plus des cas dont les valeurs sont consécutives ou presque consécutives, toujours utiliser un commutateur.
Si vous avez 2 cas, utiliser une instruction if.
Pour toute autre situation, l'interrupteur est plus susceptibles plus rapide, mais il n'est pas garanti, car le binaire de recherche dans LookupSwitch pourrait frapper un mauvais scénario.
Aussi, gardez à l'esprit que la JVM va exécuter JIT optimisations si les déclarations qui vont essayer de le lieu le plus chaud de la branche en premier dans le code. Ceci est appelé la "Direction de la Prévision". Pour plus d'informations sur cette question, voir ici: https://dzone.com/articles/branch-prediction-in-java
Votre expérience peut varier. Je ne sais pas que la JVM n'est pas un similaire sur l'optimisation des LookupSwitch, mais j'ai appris à faire confiance à l'équipe d'optimisations et de ne pas essayer de déjouer le compilateur.
switch
une plus puissante fonctionnalité du langage. La correspondance de modèle, par exemple, permettra beaucoup plus lisse et performantinstanceof
recherches. Cependant, je pense qu'il est sûr de supposer que, pour de base du commutateur/si les scénarios, la règle que j'ai mentionnés ne s'appliquent toujours.Donc, si vous envisagez d'avoir des charges de paquets de mémoire n'est pas vraiment un gros coût de ces jours et les tableaux sont assez rapide. Vous aussi ne peut pas compter sur une instruction switch pour générer automatiquement un saut de la table et en tant que tel, il est plus facile de générer le saut scénario de table vous-même. Comme vous pouvez le voir dans l'exemple ci-dessous, nous supposons un maximum de 255
des paquets.
Pour obtenir le résultat ci-dessous votre besoin abstraction.. je ne vais pas vous expliquer comment cela fonctionne, alors j'espère que vous avez une compréhension de qui.
J'ai mis à jour cette option pour définir la taille des paquets à 255 si vous avez besoin de plus alors que vous aurez à faire une vérification de limites pour (id < 0) || (id > la longueur).
Modifier depuis que j'utilise un Saut de Table en C++ beaucoup maintenant je vais vous montrer un exemple d'un pointeur de fonction de saut de la table. C'est un très générique exemple, mais je n'ai couru et il fonctionne correctement. Gardez à l'esprit que vous devez définir le pointeur à NULL, C++ va pas le faire automatiquement comme dans Java.
Aussi un autre point que je tiens à apporter est le fameux " Diviser et Conquérir. Donc, mon au-dessus de 255 tableau idée pourrait être réduite à pas plus de huit (8) si les déclarations dans le pire des cas.
I. e. mais gardez à l'esprit qu'il est confus et difficile à gérer rapidement et mon autre approche est généralement mieux, mais c'est utiliser dans les cas où les tableaux, ne suffit pas. Vous devez comprendre votre cas d'utilisation, et lorsque chaque situation qui fonctionne le mieux. Tout comme vous ne voulez pas utiliser une de ces approches si vous n'avez que peu de contrôles.
0 <= id < packets.length
et assurerpackets[id]!=null
et puis nepackets[id].execute(data)
?Au niveau du bytecode, sous réserve de la variable est chargé qu'une seule fois dans le processeur de registre à partir d'une adresse de mémoire dans la structure .classe fichier chargé par l'Exécution,et c'est dans une instruction switch; alors que dans un if, un autre jvm instruction est produite par votre compilation de code DE, et cela exige que chaque variable d'être chargées dans des registres bien que même variable est utilisée comme dans le suivant, précédent, si l'instruction. Si vous connaissez le codage en langage d'assemblage puis ce serait monnaie courante; bien que java compilé coxes ne sont pas bytecode, ou directement en code machine, le conditionnel concept des présentes est toujours conforme.
Eh bien, j'ai essayé d'éviter le plus profond de la technicité à expliquer. J'espère que j'avais fait de la notion claire et démystifié. Merci.