107 votes

Python optimise-t-il une variable qui n'est utilisée que comme valeur de retour?

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.

Est-ce que Python les transforme 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
 

139voto

Jim Points 8793

Non, il n'est pas.

La compilation Disponible en byte code est transmis uniquement par le biais d'un petit judas optimiseur qui est conçu pour ne faire que de base optimisations (Voir test_peepholer.py dans la suite de tests pour en savoir plus sur ces optimisations).

Pour prendre un coup d'oeil à ce qui se passe réellement à se produire, utiliser dis* voir les instructions générées. Pour la première fonction, contenant de la mission:

from dis import dis
dis(func)
  2           0 LOAD_CONST               1 (42)
              2 STORE_FAST               0 (a)

  3           4 LOAD_FAST                0 (a)
              6 RETURN_VALUE

Alors que, pour la seconde fonction:

dis(func2)
  2           0 LOAD_CONST               1 (42)
              2 RETURN_VALUE

Deux de plus (rapide) instructions sont utilisées dans la première: STORE_FAST et LOAD_FAST. Ceux-ci font une rapide magasin et prenez de la valeur en fastlocals tableau de l'exécution en cours du cadre. Puis, dans les deux cas, un RETURN_VALUE est effectuée. Ainsi, le deuxième n'est jamais si légèrement plus rapide en raison de la baisse des commandes nécessaires à l'exécution.

En général, sachez que le compilateur est Disponible conservateur dans les optimisations qu'il effectue. Il n'est pas et n'essayez pas d'être aussi intelligent que d'autres compilateurs (qui, en général, ont aussi beaucoup plus d'informations pour travailler avec). Le principal objectif de la conception, à part évidemment être exacte, c'est pour a) garder les choses simples et b) être aussi rapide que possible dans l'élaboration de ces de sorte que vous ne remarquerez même pas qu'une phase de compilation existe.

En fin de compte, vous ne devriez pas vous déranger avec de petites questions comme celle-ci. L'avantage de la vitesse est minuscule, constante et, éclipsés par l'overhead introduit par le fait que Python est interprété.

*dis est un petit module Python qui dis-assemble votre code, vous pouvez l'utiliser pour voir le bytecode Python que la machine virtuelle s'exécute.

Remarque: Comme il est également indiqué dans un commentaire de @Jorn Vernee, il est spécifique de la Disponible de la mise en œuvre de Python. D'autres implémentations peuvent faire des optimisations agressives si elles le souhaitent, Disponible ne l'est pas.

3voto

mario23 Points 322

Les deux sont fondamentalement les mêmes, sauf que dans le premier cas, l'objet 42 est tout simplement aassigned à une variable nommée a ou, en d'autres mots, les noms (c'est à dire a) se réfèrent à des valeurs ( 42) . Il ne fait pas de toute affectation, techniquement, dans le sens où il n'a jamais copies de toutes les données.

Alors qu' returning, ce nommé contraignant a est retourné dans le premier cas, tandis que l'objet 42 est de retour dans le deuxième cas.

Pour en savoir plus, consultez cet excellent article par Ned Batchelder

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X