Nous savons qu'il est coûteux d'attraper des exceptions. Mais est-il également coûteux d'utiliser un bloc try-catch en Java même si une exception n'est jamais levée?
J'ai trouvé la question / réponse Stack Overflow Pourquoi les blocs d'essai sont-ils chers? , mais c'est pour .NET .
java
performance
try-catch
jsedano
la source
la source
try { /* do stuff */ } finally { /* make sure to release resources */ }
est légal et utilefinally
bloc en utilisant untry-with-resources
Réponses:
try
n'a presque aucun frais du tout. Au lieu de faire le travail de configurationtry
au moment de l'exécution, les métadonnées du code sont structurées au moment de la compilation de sorte que lorsqu'une exception est levée, il effectue maintenant une opération relativement coûteuse consistant à remonter la pile et à voir s'iltry
existe des blocs qui pourraient intercepter cela. exception. Du point de vue d'un profane,try
peut tout aussi bien être gratuit. C'est en fait une exception qui vous coûte - mais à moins que vous ne lanciez des centaines ou des milliers d'exceptions, vous ne remarquerez toujours pas le coût.try
a quelques coûts mineurs associés. Java ne peut pas effectuer certaines optimisations sur le code d'untry
bloc, ce qu'il ferait autrement. Par exemple, Java réorganise souvent les instructions dans une méthode pour la rendre plus rapide - mais Java doit également garantir que si une exception est levée, l'exécution de la méthode est observée comme si ses instructions, telles qu'écrites dans le code source, étaient exécutées dans l'ordre jusqu'à une ligne.Parce que dans un
try
bloc une exception peut être levée (à n'importe quelle ligne du bloc try! Certaines exceptions sont levées de manière asynchrone, comme en appelantstop
un Thread (qui est obsolète), et même en plus, OutOfMemoryError peut se produire presque n'importe où) et pourtant il peut être intercepté et le code continue à s'exécuter par la suite dans la même méthode, il est plus difficile de raisonner sur les optimisations qui peuvent être faites, donc elles sont moins susceptibles de se produire. (Quelqu'un devrait programmer le compilateur pour les faire, raisonner et garantir l'exactitude, etc. Ce serait une grande douleur pour quelque chose censé être «exceptionnel») Mais encore une fois, en pratique, vous ne remarquerez pas des choses comme ça.la source
try...finally
blocage sanscatch
empêche- t-il également certaines optimisations?Exception
objet est ce qui prend la plupart du temps.Mesurons-le, d'accord?
Sur mon ordinateur, cela imprime quelque chose comme:
Au moins dans cet exemple trivial, l'instruction try n'a eu aucun impact mesurable sur les performances. N'hésitez pas à mesurer les plus complexes.
De manière générale, je recommande de ne pas s'inquiéter du coût des performances des constructions de langage tant que vous n'avez pas la preuve d'un problème de performances réel dans votre code. Ou comme Donald Knuth mis il: « l' optimisation prématurée est la racine de tous les maux ».
la source
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
, à la fois la boucle et l'addition qu'elle contient sont présentes dans le code natif généré. Et non, les méthodes abstraites ne sont pas intégrées, car leur appelant n'est pas seulement compilé dans le temps (probablement, car il n'est pas invoqué suffisamment de fois).try
/catch
peut avoir un impact sur les performances. En effet, cela empêche JVM d'effectuer certaines optimisations. Joshua Bloch, dans «Effective Java», a déclaré ce qui suit:la source
Oui, comme les autres l'ont dit, un
try
bloc inhibe certaines optimisations sur les{}
personnages qui l'entourent. En particulier, l'optimiseur doit supposer qu'une exception peut se produire à tout moment dans le bloc, il n'y a donc aucune garantie que les instructions seront exécutées.Par exemple:
Sans le
try
, la valeur calculée à attribuerx
pourrait être enregistrée en tant que "sous-expression commune" et réutilisée pour être affectéey
. Mais à cause de la,try
il n'y a aucune garantie que la première expression ait jamais été évaluée, donc l'expression doit être recalculée. Ce n'est généralement pas un gros problème dans le code «en ligne droite», mais cela peut être significatif dans une boucle.Il convient de noter, cependant, que cela s'applique UNIQUEMENT au code JITCed. javac n'effectue qu'une quantité impressionnante d'optimisation, et il n'y a aucun coût pour l'interpréteur de bytecode pour entrer / quitter un
try
bloc. (Aucun bytecode n'est généré pour marquer les limites du bloc.)Et pour les meilleurs:
Production:
sortie javap:
Pas de "GOTO".
la source
catch/finally
cadre.finally
de bytecode, c'esttry/catch(Throwable any){...; throw any;}
And It a une instruction catch w / a frame et Throwable qui DOIT ÊTRE définie (non nulle) et ainsi de suite. Pourquoi essayez-vous d'argumenter sur le sujet, vous pouvez vérifier au moins un bytecode? La directive actuelle pour impl. of finally copie les blocs et évite la section goto (implément précédent) mais les bytecodes doivent être copiés en fonction du nombre de points de sortie.Pour comprendre pourquoi les optimisations ne peuvent pas être effectuées, il est utile de comprendre les mécanismes sous-jacents. L'exemple le plus succinct que j'ai pu trouver a été implémenté dans les macros C à l' adresse : http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
Les compilateurs ont souvent du mal à déterminer si un saut peut être localisé vers X, Y et Z, donc ils sautent les optimisations dont ils ne peuvent garantir la sécurité, mais l'implémentation elle-même est plutôt légère.
la source
Encore un microbenchmark ( source ).
J'ai créé un test dans lequel je mesure la version de code try-catch et no-try-catch en fonction d'un pourcentage d'exception. Un pourcentage de 10% signifie que 10% des cas de test avaient une division par zéro cas. Dans une situation, il est géré par un bloc try-catch, dans l'autre par un opérateur conditionnel. Voici mon tableau de résultats:
Ce qui dit qu'il n'y a aucune différence significative entre ces cas.
la source
J'ai trouvé la capture de NullPointException assez chère. Pour les opérations de 1,2 km, le temps était de 200 ms et 12 ms lorsque je l'ai géré de la même manière,
if(object==null)
ce qui était une bonne amélioration pour moi.la source