La conversion Booléen Entier en Java sans Si-États
Je me demandais si il existe un moyen de convertir une valeur de type boolean int sans l'aide si les déclarations (de ne pas rompre le pipeline). Par exemple, je pourrais écrire
int boolToInt( boolean b ){
if ( b )
return 1
return 0
Mais je me demandais si il existe un moyen de le faire sans l'instruction si, comme Python
bool = True
num = 1 * ( bool )
J'ai aussi la figure que vous pourriez faire
boolean bool = True;
int myint = Boolean.valueOf( bool ).compareTo( false );
Cela crée un objet supplémentaire, si, si c'est vraiment du gâchis et je l'ai trouvé encore plus lente que la si-état moyen (qui n'est pas forcément inefficace, a juste l'une de ses faiblesses).
- qu'entendez-vous par "ne pas rompre le pipeline"?
- Et votre deuxième morceau de code fait exactement la même chose (c'est à dire qu'il utilise un si).
- stackoverflow.com/questions/315306/is-if-expensive je pense que les adresses de la canalisation question bien
- La question est discutable. Au niveau le plus bas, quelle que soit la langue, la vérité reste que certains de ramification se produire. Et ce genre de ramification est tellement rapide qu'il peut se passer 10^n fois, n <= 10, sans avoir le temps de cligner des yeux. Donc, finalement: pourquoi importe-t-il à tous?
- voir ma réponse - bien que banal, elle peut être admissible 🙂
- Je ne vais pas cela comme une réponse car il n'est pas plus rapide, mais voici une autre façon de faire:
return (Boolean.valueOf(b).hashCode() >> 1) & 1;
La valeur de retour de type Boolean.valueOf est toujours l'une des constantes de classe, donc il n'y a pas de création de l'objet de frais généraux, mais il comporte encore deux (caché)if
s. - Pourquoi êtes-vous exactement à l'aide de booléenne au lieu de int? Juste par curiosité, parce que je pense boolean utilise autant d'espace mémoire, en tant qu'entier.
- Pourquoi la ramification se produire? Ne peut pas/ne veut pas la JVM magasin vrai que 1 et faux à zéro?
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser un booléen, sauf dans un cas. Toutefois, cela ne signifie pas qu'il y aura une branche au niveau de l'assemblage.
Si vous vérifiez le code compilé de cette méthode (par la façon dont, à l'aide de
return b ? 1 : 0;
compile pour exactement les mêmes instructions), vous verrez qu'il n'utilise pas de saut:Note: ce qui est sur hotspot serveur de 7 - vous pouvez obtenir des résultats différents sur une autre VM.
Utiliser l' ?: opérateur:
( b ? 1 : 0 )
if
ou la?:
opérateur, il est fortement probable que la JVM, en raison de JIT, permettra d'optimiser à la même exécution du bytecode par la suite, tellement...Vous pouvez utiliser le opérateur ternaire:
Si cela est considéré comme un "si", et comme il s'agit d'un "puzzle", vous pouvez utiliser une carte comme ceci:
Bien qu'en théorie, la mise en œuvre de la HashMap n'a pas besoin d'utiliser un si, en fait. Néanmoins, les "si" n'est pas en votre code.
De cours pour améliorer les performances, vous:
Ensuite, dans la méthode:
Sinon, vous pouvez utiliser le Apache Commons BooleanUtils.toInteger méthode qui fonctionne comme un charme...
J'ai trouvé une solution par le cadre. L'utilisation de comparer les Booléens.
Ce n'est pas possible directement, pas en Java, de toute façon. Vous pourriez envisager directement à l'aide d'un
int
oubyte
au lieu d'unboolean
si vous avez vraiment besoin pour éviter la branche.Il est également possible que la VM est assez intelligent pour éliminer la branche (le
if
ou?:
) lui-même dans ce cas, comme leboolean
's la représentation interne est tout à fait susceptible d'être le littéral 1 ou 0 de toute façon. Voici un article sur la façon d'examiner l'généré du code machine natif de l'Oracle JDK, et si vous avez besoin de vitesse, assurez-vous que vous utilisez le "serveur" de la JVM qu'il effectue des plus agressives d'optimisation que le "client" un.Je ne peux pas dire que je recommande ce. C'est à la fois plus lente que l'opérateur ternaire par lui-même, et il est trop intelligent pour être appelé une bonne programmation, mais il y a ceci:
Il utilise le ternaire sous les couvertures (un couple d'appels de méthode plus tard), mais il n'est pas dans votre code. Pour être juste, je serais prêt à parier qu'il y a une branche quelque part dans le Python exécution (bien que je doute seulement le pari de nickel 😉 ).
Puisque vous ne voulez pas de si /d'autre solution que votre expression est parfait, mais je voudrais changer un peu, il
Il n'y a pas de création de l'objet impliqué, Booléenne.valueOf(boolean b) renvoie un Booléen.VRAI ou Booléen.FAUX, voir l'API
Une alternative raisonnable à la ising pour le ternaire pour éviter un "si":
Remarque que je considère ce s "puzzle" de la question, de sorte que si le codage moi-même je voudrais utiliser le ternaire..
Vous pouvez essayer d'utiliser opérateur ternaire comme ce