2010-03-26 21 views
47

En another question, la respuesta aceptada sugería reemplazar una instrucción if (muy barata) en código Python con un bloque try/except para mejorar el rendimiento.Costo de manejadores de excepciones en Python

Codificando las ediciones de estilo, y suponiendo que la excepción nunca se active, ¿cuánta diferencia tiene (en cuanto al rendimiento) tener un manejador de excepciones, versus no tener uno, versus tener un comparar-cero si- ¿declaración?

+6

Cuando lo midió, ¿qué aprendió? –

+1

Pregunta relacionada: http://stackoverflow.com/questions/1835756/ – tzot

+0

Utilice try/except si las posibilidades de control van a excepción de que la parte es menor y if/else si hay más posibilidades. – shadow0359

Respuesta

67

¿Por qué no lo mides con el ? De esta forma, puede ver si es relevante para su aplicación.

bien, así que he acaba de intentar 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í, como se esperaba, no tener ningún gestor de excepciones es ligeramente más rápido (pero explota en su enfrentar cuando se produce la excepción), y try/except es más rápido que un if explícito, siempre que la condición no se cumpla.

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, la versión if es significativamente más rápida.

+1

Interesante. Entonces 'try/except' es más rápido que' if a! = 0' – Thilo

+0

@Thilo: No preguntes. Por favor, haga otra medición y publique los resultados. –

+13

@S. Lott: ¿Qué quieres decir? Él no preguntó, hizo una declaración. Sin embargo, había cambiado mi código de 'if a! = 0:' a 'if a:' después de que él había escrito su comentario (y, por cierto, eso no hizo una diferencia en el rendimiento). Tal vez esa es la razón del malentendido? –

33

Esta pregunta es en realidad la respuesta a la Design and History FAQ:

Un try/except bloque es extremadamente eficiente si no se plantean excepciones. Atrapar realmente una excepción es costoso.

+2

Me preguntaba qué tan eficiente es "extremadamente eficiente". Aparentemente es más rápido que incluso una declaración "si" muy simple. – Thilo

+0

El extracto que publicó es de [Preguntas frecuentes sobre diseño e historial] (http://docs.python.org/faq/design.html). – nitsas

9

Esta pregunta es engañosa. Si supone que la excepción es nunca se activó, ninguno es el código óptimo.

Si supone que la excepción se desencadena como parte de una condición de error, ya se encuentra fuera del ámbito de querer un código óptimo (y probablemente no lo esté manejando a un nivel tan detallado como eso).

Si está utilizando la excepción como parte del flujo de control estándar, que es la forma Pythonic de "pida perdón, no con permiso", entonces la excepción se activará y el costo dependerá del tipo de excepción. el tipo de si y el porcentaje de tiempo que estima que ocurre la excepción.

Cuestiones relacionadas