Existe-t-il une différence ultime entre les deux extraits de code suivants? Le premier attribue une valeur à une variable dans une fonction, puis renvoie cette variable. La deuxième fonction renvoie simplement la valeur directement.
Python les transforme-t-il en bytecode équivalent? L'un d'eux est-il plus rapide?
Cas 1 :
def func():
a = 42
return a
Cas 2 :
def func():
return 42
dis.dis(..)
les deux, vous voyez qu'il y a une différence , donc oui. Mais dans la plupart des applications du monde réel , la surcharge de ceci par rapport au retard du traitement dans la fonction n'est pas si grande.Réponses:
Non, ce n'est pas le cas .
La compilation en code octet CPython est uniquement transmise à travers un petit optimiseur de judas conçu pour ne faire que des optimisations de base (voir test_peepholer.py dans la suite de tests pour plus d'informations sur ces optimisations).
Pour voir ce qui va réellement se passer, utilisez
dis
* pour voir les instructions générées. Pour la première fonction, contenant l'affectation:Alors que, pour la deuxième fonction:
Deux autres instructions (rapides) sont utilisées dans la première:
STORE_FAST
etLOAD_FAST
. Celles-ci effectuent un stockage et une saisie rapides de la valeur dans lefastlocals
tableau de la trame d'exécution actuelle. Ensuite, dans les deux cas, unRETURN_VALUE
est effectué. Ainsi, la seconde est un peu plus rapide en raison de moins de commandes nécessaires à l'exécution.En général, sachez que le compilateur CPython est prudent dans les optimisations qu'il effectue. Il n'est pas et n'essaye pas d'être aussi intelligent que les autres compilateurs (qui, en général, ont également beaucoup plus d'informations sur lesquelles travailler). L'objectif principal de la conception, en plus d'être évidemment correct, est de a) rester simple et b) être aussi rapide que possible dans la compilation de ces derniers afin que vous ne remarquiez même pas qu'une phase de compilation existe.
En fin de compte, vous ne devriez pas vous soucier de petits problèmes comme celui-ci. L'avantage en vitesse est minime, constant et, éclipsé par la surcharge introduite par le fait que Python est interprété.
*
dis
est un petit module Python qui désassemble votre code, vous pouvez l'utiliser pour voir le bytecode Python que la VM exécutera.Remarque: comme indiqué également dans un commentaire de @Jorn Vernee, ceci est spécifique à l'implémentation CPython de Python. D'autres implémentations pourraient faire des optimisations plus agressives si elles le souhaitent, CPython ne le fait pas.
la source
Les deux sont fondamentalement les mêmes sauf que dans le premier cas l'objet
42
est simplement assigné à une variable nomméea
ou, en d'autres termes, les noms (iea
) font référence à des valeurs (ie42
). Il ne fait aucune affectation techniquement, dans le sens où il ne copie jamais aucune donnée.Lors de l'
return
ing, cette liaison nomméea
est retournée dans le premier cas tandis que l'objet42
est renvoyé dans le second cas.Pour plus de lecture, reportez - vous à cet excellent article de Ned Batchelder
la source