Python是否优化掉了一个变量';s仅用作返回值?

Python是否优化掉了一个变量';s仅用作返回值?,python,interpreter,python-internals,Python,Interpreter,Python Internals,以下两段代码之间有什么根本的区别吗?首先为函数中的变量赋值,然后返回该变量。第二个函数直接返回值 Python是否将它们转换为等效字节码?其中一个更快吗 案例1: def func(): a = 42 return a def func(): return 42 案例2: def func(): a = 42 return a def func(): return 42 不,没有 对CPython字节码的编译只通过一个小的程序进行,该程序设

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

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

案例1

def func():
    a = 42
    return a
def func():
    return 42
案例2

def func():
    a = 42
    return a
def func():
    return 42
不,没有

对CPython字节码的编译只通过一个小的程序进行,该程序设计为只进行基本优化(有关这些优化的更多信息,请参阅测试套件中的)

要查看实际发生的情况,请使用
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
在第一个:和中使用了另外两个(快速)指令。它们在当前执行帧的
fastlocals
数组中快速存储和获取值。然后,在这两种情况下,执行
返回值
。因此,由于需要执行的命令较少,第二个命令的执行速度稍快

通常,请注意CPython编译器在执行优化时是保守的。它不是,也没有试图像其他编译器那样聪明(一般来说,它们也有更多的信息要处理)。除了明显正确之外,主要的设计目标是a)保持简单,b)在编译这些文件时尽可能快,这样您就不会注意到编译阶段的存在

最后,你不应该为这样的小问题而烦恼。速度方面的好处是微小的、恒定的和稳定的,与Python被解释这一事实所带来的开销相形见绌

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


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

两者基本相同,只是在第一种情况下,对象
42
只是被分配到名为
a
的变量,或者换句话说,名称(即
a
)指的是值(即
42
)。它在技术上不做任何分配,因为它从不复制任何数据

return
ing时,在第一种情况下返回此命名绑定
a
,而在第二种情况下返回对象
42


要了解更多信息,请参阅

如果您在两个屏幕上都使用了
dis.dis(..)
,您会发现它们之间存在差异,所以是的。但在大多数实际应用程序中,与函数中的处理延迟相比,该函数的开销并没有那么大。有两种可能性:(a)您将在一个紧密循环中多次(即至少一百万次)调用该函数。在这种情况下,您根本不应该调用Python函数,而是应该使用numpy库之类的工具对循环进行矢量化。(b) 您不会多次调用此函数。在这种情况下,这些函数之间的速度差异太小,不值得担心。不是python人员(c++),所以我不知道它是如何工作的,但第一种情况不应该优化为第二种情况吗?一个不错的C++编译器会做出这种优化。@ NaNaOLIVER确实不这样,Python将在这里做的,甚至没有试图玩它聪明。事实上,NaNaulver的完全合理和智能猜测在回答这个问题是完全错误的,在我看来,这不是一个“自我解释”,“胡说”,“愚蠢”的问题可以通过“花点时间思考”来回答,就像TigerhawkT3让我们相信的那样。这是一个有效的、有趣的问题,尽管我多年来一直是专业的Python程序员,但我不确定答案。Python的编译器充其量是“保守的”,而不是“非常保守的”。主要的设计目标是尽快。。。所以你甚至没有注意到编译阶段的存在。”这是第二阶段,在“保持简单”之后1@AndrewDalke感谢内部人士对此的评论,我调整了措辞以解决您指出的问题。