Python是否优化了仅用作返回值的变量?

Jay*_*esh 105 python interpreter python-internals

以下两个代码片段之间是否存在任何最终差异?第一个为函数中的变量赋值,然后返回该变量.第二个函数只是直接返回值.

Python会将它们转换为等效的字节码吗?其中一个更快吗?

案例1:

def func():
    a = 42
    return a
Run Code Online (Sandbox Code Playgroud)

案例2:

def func():
    return 42
Run Code Online (Sandbox Code Playgroud)

Jim*_*ard 136

不,它没有.

CPython字节代码的编译仅通过一个小的窥孔优化器传递,该优化器仅用于进行基本优化(有关这些优化的更多信息,请参阅测试套件中的test_peepholer.py).

要查看实际发生的情况,请使用dis*查看生成的指令.对于第一个函数,包含赋值:

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
Run Code Online (Sandbox Code Playgroud)

而对于第二个功能:

dis(func2)
  2           0 LOAD_CONST               1 (42)
              2 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

在第一个中使用了两个(快速)指令:STORE_FASTLOAD_FAST.这些可以快速存储并获取fastlocals当前执行帧数组中的值.然后,在两种情况下,RETURN_VALUE执行a.因此,由于执行所需的命令较少,因此第二个会快一些.

通常,请注意CPython编译器在其执行的优化中是保守的.它不是也不会试图像其他编译器一样聪明(一般来说,它还有更多的信息可供使用).除了明显正确之外,主要的设计目标是:a)保持简单,b)尽可能快地编译这些目标,这样你甚至不会注意到存在编译阶段.

最后,你不应该为像这样的小问题困扰自己.速度的好处是微小的,不变的,并且与解释Python这一事实引入的开销相比是相形见绌的.

*dis是一个小的Python模块,可以解组您的代码,您可以使用它来查看VM将执行的Python字节码.

注意:正如@Jorn Vernee的评论中所述,这是特定于CPython的Python实现.如果他们愿意,其他实现可能会进行更积极的优化,而CPython则不然.

  • 事实上,@ NathanOliver的*完全合理且聪明*猜测这个问题的答案是完全错误的,在我看来,证明这不是一个"不言自明","无意义","愚蠢"的问题,可以通过"花点时间思考"回答,正如TigerhawkT3让我们相信的那样.这是一个有效的,有趣的问题,尽管多年来一直是一名专业的Python程序员,但我还不确定答案. (78认同)
  • 不是python人(c ++)所以我不知道它是如何在引擎盖下工作但是第一种情况不应该优化到第二种情况?一个体面的C++编译器可以进行优化. (11认同)
  • @NathanOliver它确实没有,Python会按照这里所说的做,甚至没有试图发挥它的智能. (7认同)