web-dev-qa-db-fra.com

Coût des gestionnaires d'exceptions dans Python

Dans autre question , la réponse acceptée a suggéré de remplacer une instruction if (très bon marché) dans Python par un bloc try/except pour améliorer les performances.

Mis à part les problèmes de style de codage, et en supposant que l'exception n'est jamais déclenchée, quelle différence cela fait-il (en termes de performances) d'avoir un gestionnaire d'exceptions, par opposition à n'en avoir aucun, ou d'avoir une instruction if comparée à zéro?

75
Thilo

Pourquoi ne le mesurez-vous pas en utilisant le module timeit ? De cette façon, vous pouvez voir si cela est pertinent pour votre application.

OK, je viens d'essayer ce qui suit:

import timeit

statements=["""\
try:
    b = 10/a
except ZeroDivisionError:
    pass""",
"""\
if a:
    b = 10/a""",
"b = 10/a"]

for a in (1,0):
    for s in statements:
        t = timeit.Timer(stmt=s, setup='a={}'.format(a))
        print("a = {}\n{}".format(a,s))
        print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))

Résultat:

a = 1
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.25 usec/pass

a = 1
if a:
    b = 10/a
0.29 usec/pass

a = 1
b = 10/a
0.22 usec/pass

a = 0
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.57 usec/pass

a = 0
if a:
    b = 10/a
0.04 usec/pass

a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero

Ainsi, comme prévu, le fait de ne pas avoir de gestionnaire d'exceptions est légèrement plus rapide (mais explose en face lorsque l'exception se produit), et try/except est plus rapide qu'un if explicite tant que la condition n'est pas remplie.

Mais tout est dans le même ordre de grandeur et il est peu probable qu'il importe dans un sens ou dans l'autre. Ce n'est que si la condition est réellement remplie que la version if est nettement plus rapide.

92
Tim Pietzcker

Cette question trouve sa réponse dans la FAQ sur la conception et l'historique :

Un bloc try/except est extrêmement efficace si aucune exception n'est levée. En fait, attraper une exception coûte cher.

47
Michael

Cette question est trompeuse. Si vous supposez que l'exception est jamais déclenchée, ni l'un ni l'autre n'est un code optimal.

Si vous supposez que l'exception est déclenchée dans le cadre d'une condition d'erreur, vous êtes déjà en dehors du domaine de vouloir un code optimal (et vous ne le gérez probablement pas à un niveau fin comme celui de toute façon).

Si vous utilisez l'exception dans le cadre du flux de contrôle standard - qui est la méthode Pythonique "demander pardon, pas autorisation" - alors l'exception va être déclenchée, et le coût dépend du type d'exception, du type de si et quel pourcentage de temps vous estimez que l'exception se produit.

15
user79758