Ce qui est plus rapide, essayez de l'attraper ou si-sinon en java (WRT performance)
Lequel est le plus rapide:
Soit ce
try {
n.foo();
}
catch(NullPointerException ex) {
}
ou
if (n != null) n.foo();
- Comment à propos de "Qui est plus lisible?" La Performance est votre dernière préoccupation.
- Utilisation de try-catch clause de cette façon est certainement une mauvaise idée. Aussi try-catch résultats dans instantinating de new object (l'exception). Donc je dirais que (n!=null) est plus rapide dans le cas où vous avez un grand nombre de cas où n == null. Aussi n!=la valeur null est ultra-rapide à construire.
- La Performance est très différente selon que n est nul ou pas.
- "Aussi try-catch résultats dans instantinating de new object (l'exception)". Non, il n'est pas. Lancer une exception ne.
- Hmm, bizarre que c'est le sujet du dernier Javaspecialists bulletin de quiz. Heinz M. Kabutz ne soutiennent que la première forme est en effet très mauvais pour la performance. Il n'est cependant fournir une information supplémentaire: n est nulle de 10% du temps.
- Ils sont différents... la première forme sera aussi attraper les Npe générée à partir de foo()
- il ne le fait pas. Lancer une exception ne." Non, il n'est pas. 😉 La construction de la levée d'une exception n'. Du code peut choisir volontairement lever de nouveau la même exception, encore et encore (aussi fou que ça puisse être). Désolé, j'ai juste eu à rajouter. 🙂
- Dans le très ancien des jours exceptions ont été lents (car ils ont capturé la trace de la pile lors de la génération). Aujourd'hui, ils sont plus rapides, mais il reste encore beaucoup de travail qui est inutile dans ce cas.
- Je suis venu ici demandais la même chose. Ce sujet le cas où vous êtes à la recherche pour une condition qui se produit une fois, et une seule fois (parce que vos prises block fait une initialisation de la base de l'information dans un argument), sur un programme qui pourrait fonctionner pendant des heures? En gros, est-ce plus rapide de passer par un essai qui réussit toujours que SI c'est toujours vrai? Est-il un coût à long terme à un essai qui réussit toujours? En Python, ils encouragent ce genre de chose - pourquoi le cours de l'histoire en Java?
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas une question de qui est plus rapide, mais plutôt de justesse.
Une exception est pour les circonstances qui sont exactement ce que, exceptionnelle.
Si c'est possible pour
n
êtrenull
dans le cadre normal des affaires, de la logique, puis utiliser uneif..else
, d'autrethrow
une exception.est plus rapide.
for
déclaration ou serait-ce la méthode la plus rapide dans ce cas?Explicitement de test pour un pointeur null est beaucoup plus rapide que la gestion des exceptions.
Pour l'enregistrement, plus de la oherheads en utilisant les exceptions sont engagés dans la instanciation de l'objet de l'exception. En particulier dans l'appel à
fillInStackTrace()
qui a pour:Dans certains cas, vous pouvez réduire ce en réutilisant l'objet de l'exception, ou par substitution d'une application spécifique exception du
fillInStackTrace()
méthode pour en faire un no-op. La baisse dans les deux cas, c'est que bon stacktraces ne seront plus disponibles pour vous aider à déboguer des exceptions inattendues. (Et aucune de ces sont applicables à l'OP de l'exemple.)Alors que l'exception de l'instanciation est cher, à l'exception de lancer, de propagation et de rattrapage ne sont pas exactement bon marché non plus.
Il y a une deuxième raison pour laquelle explicite null test est une meilleure idée. Considérez ceci:
Ce qui se passe si une NPE se passe au sein de l'appel à
doSomething(...)
au lieu de cours de l'évaluation de laa.field
expression? Bien sûr, nous allons attraper un NPE, mais nous allons faire une erreur de diagnostic, et ensuite essayer de continuer ... supposant à tort quea.field
n'est pas défini ou quelque chose.À distinguer un "attendu" NPE à partir d'un "imprévu" NPE est possible en théorie, mais en pratique très difficile. Beaucoup plus simple et plus robuste approche est explicitement test pour la
null
valeurs que vous attendez (par exemple avec unif
déclaration), et de traiter toutes les Npe comme des bugs.(Je suis sûr que c'est ce @Mitch entend par "traitement des exceptions exceptionnelles", mais je pense qu'il est utile de préciser les choses avec un exemple ...)
Exception
objet, puis de le jeter à plusieurs reprises (pour simuler unebreak
déclaration de l'intérieur d'une fermeture), est très rapide.La réponse n'est pas aussi simple qu'il y paraît, car cela dépendra du pourcentage de fois que l'objet est vraiment nul. Lorsque cela est très rare (disons de 0,1% du temps), il pourrait même être plus rapide. Pour tester ce que j'ai fait quelques comparaisons avec les résultats suivants (avec la version 1.6 de Java client):
Cela semble assez concluante pour moi. NPE sont juste très lent. (Je peux poster le benchmarking code si vous le souhaitez)
edit:
Je viens de faire une découverte intéressante: lorsque l'analyse comparative à l'aide de la JVM de serveur, les résultats changent radicalement:
À l'aide du serveur de VM, la différence est à peine visible. Encore: je préfère ne pas utiliser la capture de NullPointerException moins que c'est vraiment une exception.
execute
méthodes ont été efficacement no-ops et optimisé loin. Aussi. vous ne faites rien pour s'assurer que les méthodes sont JIT compilé, ou pour permettre la surcharge du PROCESSEUR de compilation JIT.java.lang.Object
instances et que latoString()
ainsi, les appels sont sans effets secondaires. Vous avez vraiment besoin de changer les critères de référence de sorte que les valeurs des expressions sont utilisées. Par exemple, faire de les objetsInteger
instances et la somme de leursintValue()
valeurs.Si
n.foo()
arrive à lancer en interne un NPE, vous partez pour une longue session de débogage (ou pire encore, votre application échoue dans la production..). Il suffit de ne pas le faire.Combien de nano-secondes envisagez-vous d'enregistrer, de toute façon?
Je remarque que je ne suis pas le seul à lire le Java du Spécialiste de la Newsletter 🙂
Outre le fait qu'il y a un différence sémantique (les entrées en phase nationale n'est pas nécessairement causée par référence à
n
, il pourrait avoir été jeté par une erreur dansfoo()
), et un lisibilité question (le try/catch est plus déroutant pour un lecteur que l'if
), ils devraient être tout aussi rapide dans le cas oùn != null
(avec le si/d'autre version ayant un léger avantage), mais quandn == null
si/d'autre est beaucoup plus rapide. Pourquoi?n == null
, la machine virtuelle doit créer une nouvelle exception à l'objet et de remplir ses trace de la pile. La trace de la pile de l'info, c'est vraiment cher à acquérir, voici donc le try/catch version est beaucoup plus cher.if
ils pensent qu'ils s'en aille pas cher quandn != null
. La chose est, cependant, que la VM va faire un implicite null vérifier quand déréférencement... qui est, à moins que l'équipe peut déterminer quen
doit être non null, qu'il peut dans le si/d'autre version. Cela signifie que le if/else et try/catch versions devraient être effectuer environ le même. Mais...À côté de la bonne réponse (utilisation des exceptions pour des cas exceptionnels), je vois que vous êtes essentiellement en essayant d'éviter les nuls vérifie partout. Java 7 aura un "null sécuritaire" de l'opérateur qui va retourner la valeur null lorsque
n?.foo()
est appelé au lieu de lancer des NPE. C'est empruntée au langage Groovy. Il y a aussi une tendance à éviter d'utiliser la valeur null tout à fait dans son code, sauf lorsque c'est vraiment nécessaire (c'est à dire: le contact avec les bibliothèques). Voir cette autre réponse, pour plus de discussion sur ce point.Éviter != null états
Il est généralement coûteux à gérer les exceptions. Le VM Spec peut vous donner un aperçu de la façon dont beaucoup, mais dans le cas ci-dessus
if (n != null) n.foo();
est plus rapide.Bien que je suis d'accord avec Mitch Blé concernant la vraie question est la décision correcte.
@Mitch Blé Dans sa défense, c'est un joli exemple artificiel. 🙂
La si construction est plus rapide. La condition peut être facilement traduit en code machine (processeur des instructions).
L'alternative (try-catch) nécessite la création d'une NullPointerException objet.
Certainement la deuxième forme est beaucoup plus rapide. Dans le
try-catch
scénario, il jette unexception
qui ne unnew Exception()
de certaine forme. Puis lecatch
bloc est appelé qui est un appel de méthode et doit exécuter n'importe quel code est en elle. Vous obtenez l'idée.Tout d'abord le if.. then .. else est mieux, pour de multiples raisons l'ont souligné les autres affiches.
Cependant, il n'est pas necceseraly plus vite! Il dépend entirly sur la ration des objets nuls pour ne pas null objets. Il prend sans doute une des centaines de milliers de fois les ressources pour le processus d'une exception plutôt que de tester la valeur null, cependant, si un objet nul ne se produit qu'une fois par million d'objets, puis l'exception de l'option sera légèrement plus rapide. Mais pas beaucoup plus rapide que sa vaut la peine de faire votre programme en moins lisible et plus difficile à déboguer.
if-else est plus rapide, car un bloc try-catch soulève une trace de pile d'exception.
Vous pouvez le prendre comme la Si-bloc Else est en cours d'exécution d'une instruction à procéder à l'évaluation, mais le Try-Catch sera exécuté des milliers d'instructions de lever l'exception quand il arrive.
Ce problème a été discuté récemment par le Dr Heinz:
http://javaspecialists.eu/webinars/recordings/if-else-npe-teaser.mov