Coste de los manejadores de excepciones en Python


En otra pregunta, la respuesta aceptada sugirió reemplazar una instrucción if (muy barata) en código Python con un bloque try/except para mejorar el rendimiento.

Dejando de lado los problemas de estilo de codificación, y suponiendo que la excepción nunca se activa, ¿cuánta diferencia hace (en términos de rendimiento) tener un manejador de excepciones, frente a no tener uno, frente a tener una sentencia compare-to-zero if-statement?

Author: Community, 2010-03-26

3 answers

¿Por qué no lo mides usando el timeit módulo? De esa manera puedes ver si es relevante para tu aplicación.

OK, así que acabo de probar lo siguiente:

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

Resultado:

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

Así que, como era de esperar, no tener ningún controlador de excepciones es ligeramente más rápido (pero te explota en la cara cuando ocurre la excepción), y try/except es más rápido que un if explícito siempre y cuando no se cumpla la condición.

Pero todo está dentro del mismo orden de magnitud y es poco probable que importe de cualquier manera. Solo si la condición se cumple realmente, entonces la versión if es significativamente más rápida.

 77
Author: Tim Pietzcker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-26 10:25:37

Esta pregunta en realidad se responde en el Diseño e Historia FAQ :

Un bloque try/except es extremadamente eficiente si no se generan excepciones. En realidad, atrapar una excepción es caro.

 41
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-30 12:14:48

Esta pregunta es engañosa. Si asume que la excepción es nunca activada, ninguna de ellas es el código óptimo.

Si asume que la excepción se activa como parte de una condición de error, ya está fuera del ámbito de querer un código óptimo (y probablemente no lo esté manejando a un nivel detallado como ese de todos modos).

Si está utilizando la excepción como parte del flujo de control estándar, que es la forma pitónica de "pedir perdón, no permiso" , entonces la excepción va a ser activado, y el costo depende del tipo de excepción, el tipo de si, y qué porcentaje de tiempo se estima que la excepción sucede.

 11
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-18 21:12:39