Python 是否优化掉仅用作 return 值的变量?

Does Python optimize away a variable that's only used as a return value?

以下两个代码片段之间有什么根本区别吗?第一个为函数中的变量赋值,然后 returns 该变量。第二个函数直接 returns 值。

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

案例 1:

def func():
    a = 42
    return a

案例 2:

def func():
    return 42

没有,没有

编译为 CPython 字节码仅通过测试套件中的一小部分 peephole optimizer that is designed to do only basic optimizations (See 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

而对于第二个函数:

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

在第一个中使用了另外两条(快速)指令:STORE_FAST and LOAD_FAST。这些可以快速存储和获取当前执行帧的 fastlocals 数组中的值。然后,在这两种情况下,都会执行 RETURN_VALUE。因此,第二个 稍微 更快,因为需要执行的命令更少。

一般来说,请注意 CPython 编译器在其执行的优化方面 保守 。它不是,而且 也不会尝试 与其他编译器一样聪明(通常,它们也有更多的信息可供使用)。主要的设计目标,除了显然是正确的,是 a) 保持简单和 b) 在编译这些时尽可能 swift 这样你甚至不会注意到编译阶段的存在。

总之,你不应该为这样的小问题而烦恼。速度方面的好处是微小的,恒定的,并且与 Python 被解释这一事实引入的开销相比相形见绌。

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

注意: 正如@Jorn Vernee 的评论中所述,这是特定于 Python 的 CPython 实现。其他实现可能会根据需要进行更积极的优化,CPython 不会。

两者基本相同,只是在第一种情况下对象 42 被简单地分配给名为 a 的变量,换句话说,名称(即 a)参考值(即 42)。从技术上讲,它不执行任何分配,因为它从不复制任何数据。

returning 时,此命名绑定 a 在第一种情况下被 returned,而对象 42 在第二种情况下被 return .

更多阅读,请参考this great article by Ned Batchelder