Python是否优化了一个只用作返回值的variables?
以下两个代码片段之间有什么最终的区别? 第一个赋值给一个函数中的variables,然后返回该variables。 第二个函数直接返回值。
Python会把它们变成等效的字节码吗? 其中一个更快?
案例1 :
def func(): a = 42 return a
案例2 :
def func(): return 42
不, 不 。
对CPython字节码的编译只能通过一个小型窥孔优化器来实现,这个优化器只能进行基本的优化(有关这些优化的更多信息,请参阅testing套件中的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
而对于第二个function:
dis(func2) 2 0 LOAD_CONST 1 (42) 2 RETURN_VALUE
第一个使用另外两个(快速)指令: STORE_FAST
和LOAD_FAST
。 这些快速存储和抓取当前执行框架的fastlocals
数组中的值。 然后,在这两种情况下,执行RETURN_VALUE
。 所以,由于需要执行的命令较less,所以第二个速度稍快。
一般来说,请注意,CPython编译器在执行优化时保守 。 这不是也不会像其他编译器那样聪明(一般而言,它们也有更多的信息可以使用)。 主要的devise目标,除了显然是正确的,是a)保持简单,b)尽可能快地编译这些,所以你甚至不会注意到编译阶段存在。
最后,你不应该像这样的小问题麻烦你自己。 速度上的好处是微小的,不变的,并且由Python解释的事实引起的开销相形见绌。
* dis
是一个可以分解代码的小Python模块,可以用它来查看VM将执行的Python字节码。
注意:正如@Jorn Vernee的评论中所述,这是针对Python的CPython实现的。 其他的实现可能会做更积极的优化,如果他们愿意,CPython不会。
两者基本相同,只是在第一种情况下,对象42
简单地分配给名为a
的variables,换句话说,名称(即a
)是指值(即42
)。 它在技术上不做任何分配,从不复制任何数据。
当return
,在第一种情况下返回该命名绑定a
,而在第二种情况下返回对象42
。
欲了解更多信息,请参阅Ned Batchelder撰写的这篇伟大的文章