web-dev-qa-db-fra.com

En Javascript, est-ce coûteux d'utiliser des blocs try-catch même si une exception n'est jamais levée?

Est-il "lent" d'utiliser plusieurs blocs try-catch lorsqu'aucune exception n'est levée dans aucun d'entre eux? Ma question est la même que celle-ci , mais pour Javascript.

Supposons que j'ai 20 fonctions qui contiennent des blocs try-catch. Et une autre fonction qui appelle chacune de ces 20 fonctions. Aucun d'eux ne lèvera d'exception. Mon code s'exécutera-t-il plus lentement ou fonctionnera-t-il bien pire à cause de ces blocs try-catch?

48
cprcrack

Faites-vous du code d'interface utilisateur CRUD typique? Utilisez des captures d'essai, utilisez des boucles qui vont à 10000 sans raison saupoudrées de votre code, diable, utilisez angular/ember - vous ne remarquerez aucun problème de performance.

Si vous faites une bibliothèque de bas niveau, des simulations physiques, des jeux, du côté serveur, etc., le bloc try-catch jamais lancé n'a normalement aucune importance, mais le problème est que V8 ne l'a pas pris en charge dans leur compilateur d'optimisation jusqu'à la version 6 du moteur, de sorte que l'intégralité de la fonction contenant qui contient syntaxiquement un try catch ne sera pas optimisée. Cependant, vous pouvez facilement contourner ce problème en créant une fonction d'assistance comme tryCatch:

function tryCatch(fun) {
    try {
        return fun();
    }
    catch(e) {
        tryCatch.errorObj.e = e;
        return tryCatch.errorObj;
    }
}
tryCatch.errorObj = {e: null};


var result = tryCatch(someFunctionThatCouldThrow);
if(result === tryCatch.errorObj) {
    //The function threw
    var e = result.e;
}
else {
    //result is the returned value
}

Après la version 6 de V8 (fournie avec Node 8.3 et dernière version de Chrome), les performances du code à l'intérieur de try-catch est le même que celui du code normal.

48
Esailija

La question d'origine portait sur le coût de try/catch lorsqu'une erreur n'était pas levée. Il y a certainement un impact lors de la protection d'un bloc de code avec try/catch, mais l'impact de try/catch disparaîtra rapidement car le code protégé devient même légèrement complexe.

Considérez ce test: http://jsperf.com/try-catch-performance-jls/2

Un incrément simple s'exécute à 356 800 000 itérations par seconde. Le même incrément dans un essai/capture est de 93 500 000 itérations par seconde. C'est sur les frais généraux de 75% en raison de try/catch. MAIS, un appel de fonction trivial s'exécute à 112 200 000 itérations par seconde. 2 appels de fonction triviaux s'exécutent à 61 300 000 itérations par seconde.

Un essai non exercé dans ce test prend un peu plus de temps qu'un appel de fonction trivial. Ce n'est guère une pénalité de vitesse qui compte, sauf dans la boucle la plus interne de quelque chose de vraiment intense comme une FFT.

Le cas que vous souhaitez éviter est le cas où une exception est réellement levée. C'est immensément plus lent, comme le montre le lien ci-dessus.

Edit: Ces chiffres sont pour Chrome sur ma machine. Dans Firefox, il n'y a pas de différence significative entre un essai non exercé et aucune protection du tout. Il n'y a essentiellement aucune pénalité à utiliser try/catch si aucune exception n'est jeté.

36
asthomas

Le try-catch le bloc serait coûteux. Cependant, si les performances critiques ne sont pas un problème, leur utilisation n'est pas nécessairement un problème.

La sanction IMO est:

  • lisibilité
  • inapproprié dans de nombreux cas
  • inefficace en matière de programmation asynchrone

Lisibilité : plomber votre code avec beaucoup d'essais est laid et distrayant

inapproprié : c'est une mauvaise idée d'insérer un tel bloc si votre code n'est pas sujet à un crash d'exception. Insérez-le uniquement si vous prévoyez une défaillance de votre code. Jetez un œil à la rubrique suivante: Quand utiliser les blocs try/catch?

Async : le try-catch le bloc est synchrone et n'est pas efficace en ce qui concerne la programmation async. Au cours d'une demande ajax, vous gérez les événements error et success dans des rappels dédiés. Pas besoin d try-catch.

J'espère que cela t'aides,

R.

7
roland