Esta es una pregunta de seguimiento al an answer I gave a few days back. Editar: parece que el OP de esa pregunta ya usó el código que le envié para preguntar the same question, pero no lo sabía. Disculpas ¡Las respuestas proporcionadas son diferentes!¿Por qué el retorno anticipado es más lento que otro?
Sustancialmente he observado que:
>>> def without_else(param=False):
... if param:
... return 1
... return 0
>>> def with_else(param=False):
... if param:
... return 1
... else:
... return 0
>>> from timeit import Timer as T
>>> T(lambda : without_else()).repeat()
[0.3011460304260254, 0.2866089344024658, 0.2871549129486084]
>>> T(lambda : with_else()).repeat()
[0.27536892890930176, 0.2693932056427002, 0.27011704444885254]
>>> T(lambda : without_else(True)).repeat()
[0.3383951187133789, 0.32756996154785156, 0.3279120922088623]
>>> T(lambda : with_else(True)).repeat()
[0.3305950164794922, 0.32186388969421387, 0.3209099769592285]
... o en otras palabras: con la cláusula else
es más rápida, independientemente de la condición if
ser activado o no.
Supongo que tiene que ver con diferentes bytecode generados por los dos, pero ¿alguien puede confirmar/explicar en detalle?
EDIT: Parece que no todo el mundo puede reproducir mis tiempos, así que pensé que podría ser útil dar algo de información sobre mi sistema. Estoy ejecutando Ubuntu 11.10 de 64 bits con el pitón predeterminado instalado. python
genera la siguiente información de la versión:
Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Éstos son los resultados del desmontaje en Python 2.7:
>>> dis.dis(without_else)
2 0 LOAD_FAST 0 (param)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
4 >> 10 LOAD_CONST 2 (0)
13 RETURN_VALUE
>>> dis.dis(with_else)
2 0 LOAD_FAST 0 (param)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
5 >> 10 LOAD_CONST 2 (0)
13 RETURN_VALUE
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
había una pregunta idéntica en SO No puedo encontrar ahora. Verificaron el bytecode generado y hubo un paso adicional. Las diferencias observadas fueron muy dependientes del probador (máquina, SO ...), a veces encontrando diferencias muy pequeñas. – joaquin
En 3.x, ambos producen ** bytecode ** guardado para un código inalcanzable ('LOAD_CONST (None); RETURN_VALUE' - pero como se dijo, nunca se alcanza) al final de' with_else'. Dudo mucho que el código muerto haga que una función sea más rápida. ¿Podría alguien proporcionar un 'dis' en 2.7? – delnan
No pude reproducir esto. La función con 'else' y' False' fue la más lenta de todas (152ns). El segundo más rápido fue 'True' sin' else' (143ns) y otros dos fueron básicamente iguales (137ns y 138ns). No utilicé el parámetro predeterminado y lo medí con '% timeit' en iPython. – rplnt