¿Existe alguna diferencia fundamental entre los siguientes dos fragmentos de código? El primero asigna un valor a una variable en una función y luego devuelve esa variable. La segunda función simplemente devuelve el valor directamente.
¿Python los convierte en un código de bytes equivalente? ¿Es uno de ellos más rápido?
Caso 1 :
def func():
a = 42
return a
Caso 2 :
def func():
return 42
python
interpreter
python-internals
Jayesh
fuente
fuente
dis.dis(..)
en ambos ves que hay una diferencia , así que sí. Pero en la mayoría de las aplicaciones del mundo real , la sobrecarga de esto comparada con el retraso del procesamiento en la función no es tanto.Respuestas:
No, no es así .
La compilación al código de bytes CPython solo se pasa a través de un pequeño optimizador de mirilla que está diseñado para realizar solo optimizaciones básicas (consulte test_peepholer.py en el conjunto de pruebas para obtener más información sobre estas optimizaciones).
Para ver lo que realmente va a suceder, use
dis
* para ver las instrucciones generadas. Para la primera función, que contiene la asignación:Mientras que, para la segunda función:
Se utilizan dos instrucciones más (rápidas) en la primera:
STORE_FAST
yLOAD_FAST
. Estos hacen un almacenamiento rápido y capturan el valor en lafastlocals
matriz del marco de ejecución actual. Luego, en ambos casos,RETURN_VALUE
se realiza a. Entonces, el segundo es ligeramente más rápido debido a que se necesitan menos comandos para ejecutar.En general, tenga en cuenta que el compilador CPython es conservador en las optimizaciones que realiza. No es ni intenta ser tan inteligente como otros compiladores (que, en general, también tienen mucha más información con la que trabajar). El objetivo principal del diseño, además de ser obviamente correcto, es a) mantenerlo simple yb) ser lo más rápido posible al compilarlos para que ni siquiera se dé cuenta de que existe una fase de compilación.
Al final, no deberías preocuparte por pequeños problemas como este. El beneficio de la velocidad es pequeño, constante y empequeñecido por la sobrecarga introducida por el hecho de que se interpreta Python.
*
dis
es un pequeño módulo de Python que desensambla su código, puede usarlo para ver el código de bytes de Python que ejecutará la VM.Nota: Como también se indicó en un comentario de @Jorn Vernee, esto es específico de la implementación CPython de Python. Otras implementaciones pueden hacer optimizaciones más agresivas si así lo desean, CPython no lo hace.
fuente
Ambos son básicamente iguales, excepto que en el primer caso el objeto
42
simplemente se asigna a una variable nombradaa
o, en otras palabras, los nombres (es decira
) se refieren a valores (es decir42
). No realiza ninguna asignación técnicamente, en el sentido de que nunca copia ningún dato.Mientras
return
ing, este enlace con nombrea
se devuelve en el primer caso, mientras que el objeto42
se devuelve en el segundo caso.Para leer más, consulte este gran artículo de Ned Batchelder
fuente