Dans la section Quand utiliser l'exception dans The Pragmatic Programmer , le livre écrit qu'au lieu de:
retcode = OK;
if (socket.read(name) != OK) {
retcode = BAD_READ;
}
else {
processName(name);
if (socket.read(address) != OK) {
retcode = BAD_READ;
}
else {
processAddress(address);
if (socket.read(telNo) != OK) {
retcode = BAD_READ;
}
else {
// etc, etc...
}
}
}
return retcode;
, ils préfèrent:
retcode = OK;
try {
socket.read(name);
process(name);
socket.read(address);
processAddress(address);
socket.read(telNo);
// etc, etc...
}
catch (IOException e) {
retcode = BAD_READ;
Logger.log( "Error reading individual: " + e.getMessage());
}
return retcode;
tout simplement parce qu'il a l'air plus soigné. Je suis tout pour le code plus propre, est cependant pas inutile saisie d' une exception d' un goulot d'étranglement?
Je peux comprendre que nous devrions abandonner l'optimisation minuscule pour le code plus propre (au moins 99% du temps), mais d'après ce que je sais, les exceptions de capture appartiennent à la classe de code qui a un retard notable dans l'exécution. Par conséquent, je me demandais quelle est la justification que le deuxième morceau de code est préféré au premier code?
Ou plutôt, quel code préférez-vous?
java
exception-handling
language-agnostic
Pacerier
la source
la source
Réponses:
Les exceptions ne sont généralement plus lentes que si elles sont effectivement levées. Habituellement, les exceptions dans des situations comme celle-ci sont rares, donc ce n'est pas quelque chose dont vous devriez vous inquiéter. Vous ne devez vraiment vous soucier des performances des exceptions que si elles se produisent tout le temps et sont donc un facteur important.
Le deuxième code est meilleur car il est beaucoup plus facile de suivre la logique. La gestion des erreurs est bien localisée. La seule objection est que si vous utilisez des exceptions, utilisez des exceptions. N'attrapez pas les exceptions, puis retournez un code d'erreur.
la source
Eh bien, comme ils le disent aussi, les exceptions devraient traiter les cas exceptionnels , et comme il s'agit d'un cas exceptionnel (c'est-à-dire quelque chose qui se produit peu et loin entre les deux), je dirais que cela s'applique également ici.
De plus, je vous conseille contre les choses micro-optimisation de ce genre. Concentrez-vous davantage sur la lisibilité du code , car vous passerez beaucoup plus de temps à lire du code qu'à écrire un nouveau code.
Pour vraiment vous assurer qu'il s'agit d'un goulot d'étranglement des performances, effectuez un profilage, analysez et concentrez-vous sur les tâches les plus critiques basées sur cette analyse.
la source
D'où le savez-vous? Comment définissez-vous le "retard notable"?
C'est exactement le genre de mythe de la performance vague (et complètement faux) qui conduit à des optimisations prématurées inutiles.
Lancer et intercepter une exception peut être lent par rapport à l'ajout de deux nombres, mais c'est complètement insignifiant par rapport à la lecture de données à partir d'un socket. Vous pourriez probablement lever et intercepter mille exceptions en même temps que vous lisez un seul paquet réseau. Et nous ne parlons pas ici de milliers d'exceptions, seulement d'une seule.
la source
Je suis d'accord avec les réponses que vous avez déjà obtenues en disant qu'il s'agit d'un cas exceptionnel, il est donc raisonnable d'utiliser la gestion des exceptions.
Pour répondre plus directement à vos préoccupations en matière de performances, je pense que vous devez garder une idée de l'échelle des choses. Lancer / attraper une exception dans ces circonstances est susceptible de prendre un de l'ordre de la microseconde. Comme le contrôle de flux va, c'est lent - plusieurs fois plus lent que les
if
instructions normales , cela ne fait aucun doute.Dans le même temps, gardez à l'esprit que ce que vous faites ici, c'est la lecture des données d'un réseau. À 10 mégabits par seconde (lent pour un réseau local, mais assez rapide pour les connexions Internet), c'est dans le même ordre que le temps de lire un octet d'informations.
Bien sûr, ces frais généraux ne sont encourus que lorsque vous lâchez également l'exception - lorsqu'il n'est pas levé, il y a généralement peu ou pas de frais généraux (du moins d'après ce que j'ai vu, le surdébit le plus significatif ne provient pas du gestion des exceptions elle-même, comme l'ajout de plus de flux de contrôle potentiels, ce qui rend le code plus difficile à optimiser pour le compilateur).
Dans ce cas, lorsqu'une exception est levée, vos données d'écriture dans le journal. Compte tenu de la nature de la journalisation, il est fort probable que vous vidiez cette sortie dès que vous l'écrivez (pour vous assurer qu'elle n'est pas perdue). L'écriture sur le disque est (encore une fois) une opération assez lente - vous avez besoin d'un SSD de classe entreprise assez rapide pour atteindre même des dizaines de milliers d'IOP / seconde. Un disque utilisé pour la journalisation peut facilement être limité à quelque chose comme des centaines d'IOP / seconde.
Conclusion: il existe des cas où la surcharge de traitement des exceptions peut être importante, mais ce n'est certainement pas l' un d'entre eux.
la source