36 votes

Quoi de plus rapide, essayez catch ou if-else en java (performances WRT)

Ce qui est plus rapide:

 try {
  n.foo();
} 
catch(NullPointerException ex) {
}
 

ou

 if (n != null) n.foo();
 

54voto

Mitch Wheat Points 169614

Ce n'est pas une question qui est plus rapide, mais plutôt une question de correction.

Une exception est pour des circonstances qui sont exactement cela, exceptionnelles .

S'il est possible que n soit null dans le cadre de la logique métier normale, utilisez une if..else , sinon throw une exception.

52voto

Boris Pavlović Points 22207
 if (n != null) n.foo();
 

est plus rapide.

36voto

Stephen C Points 255558

Explicitement de test pour un pointeur null est beaucoup plus rapide que la gestion des exceptions.

Pour l'enregistrement, la plupart des oherheads en utilisant les exceptions sont engagés dans l' instanciation de l'objet de l'exception. En particulier dans l'appel d' fillInStackTrace() qui doit:

  • examiner chaque frame de pile pour la pile du thread actuel, et
  • créer une structure de données pour capturer le cadre de la pile de détails.

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 de l' 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. Réfléchissez à ceci:

try {
    doSomething(a.field);
} catch (NullPointerException ex) {
    System.err.println("a.field is null");
}

Ce qui se passe si une NPE se passe au sein de l'appel à doSomething(...) au lieu de cours de l'évaluation de l' a.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 que a.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 l' null valeurs que vous attendez (par exemple avec un if 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 ...)

26voto

Marc Points 2482

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):

Benchmaring with factor 1.0E-4
Average time of NullIfTest: 0.44 seconds
Average time of NullExceptionTest: 0.45 seconds
Benchmaring with factor 0.0010
Average time of NullIfTest: 0.44 seconds
Average time of NullExceptionTest: 0.46 seconds
Benchmaring with factor 0.01
Average time of NullIfTest: 0.42 seconds
Average time of NullExceptionTest: 0.52 seconds
Benchmaring with factor 0.1
Average time of NullIfTest: 0.41 seconds
Average time of NullExceptionTest: 1.30 seconds
Benchmaring with factor 0.9
Average time of NullIfTest: 0.07 seconds
Average time of NullExceptionTest: 7.48 seconds

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:

Benchmaring with factor 1.0E-4
Average time of NullIfTest: 0.33 seconds
Average time of NullExceptionTest: 0.33 seconds
Benchmaring with factor 0.0010
Average time of NullIfTest: 0.32 seconds
Average time of NullExceptionTest: 0.33 seconds
Benchmaring with factor 0.01
Average time of NullIfTest: 0.31 seconds
Average time of NullExceptionTest: 0.32 seconds
Benchmaring with factor 0.1
Average time of NullIfTest: 0.28 seconds
Average time of NullExceptionTest: 0.30 seconds
Benchmaring with factor 0.9
Average time of NullIfTest: 0.05 seconds
Average time of NullExceptionTest: 0.04 seconds

En utilisant le 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.

8voto

Enno Shioji Points 12298

Si n.foo() arrive à lancer en interne un NPE, vous êtes parti pour une longue session de débogage (ou pire, votre application échoue en production ..). Ne le fais pas.

Combien de nano secondes prévoyez-vous de toute façon?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X