关键字参数性能(python)



我正试图通过使用timeit测试(计时)各种函数来优化一些python代码。

我发现,根据变量是关键字参数还是函数内的变量,我得到了不同的速度。

即:

def test_function(A = value()):
#rest of function....

返回的结果与不同

def test_function():
A = value()
#rest of function ...

我本以为他们会有非常相似的结果——我猜我不理解/错过了一些东西。。。

(也为测试做了10000个循环)

关键字参数在函数定义时求值一次。因此,在您的第一个示例中,value()只被调用一次,无论您多久调用一次测试函数。如果value()非常昂贵,这就解释了两个版本在运行时的差异。

没有理由期望您的两个函数做相同的事情,更不用说具有相同的性能特征了。

def test_function(A = value()):
#rest of function....

此函数没有"关键字参数";根本不存在这样的事情。它有一个具有默认值的参数。任何函数的任何参数(除了一些顽固的内置函数)都可以通过关键字或位置传递,但参数本质上不是"关键字参数"。

关键字参数和默认值之间的唯一关联是,当多个参数具有默认值时,向后面的参数提供显式值,同时接受前面参数的默认值的唯一方法是按关键字传递后面的参数。

这两个函数之间的巨大区别在于,当您为A声明一个默认值时,它是一个默认的,而不是一些代码,如果没有提供显式值,则每次都会重新生成该值。当你这么说的时候:

def test_function(A = value()):
#rest of function....

您正在为A设置默认的。与任何其他上下文一样,当您提供一个复杂的表达式,其中Python需要一个值时,Python将评估该表达式,然后使用结果值。因此,当您在函数定义时设置A的默认值时,它将被设置为value()当时返回的任何值。那么这一个值就是A的默认值。

def test_function():
A = value()
#rest of function ...

在该函数中,每次调用函数时都会对value()进行求值。因此,如果value()价格昂贵,那么这个版本将比第一个版本花费更长的时间。但是,如果value()返回一个稍后发生变化的对象,那么默认的参数版本将始终使用一个对象,无论它在调用函数时处于什么状态,而第二个版本每次都将构造一个新的value。您使用的版本应该由您希望程序具有的语义决定。

有人讨论为什么这种方法不是确定方法有效性的最佳方法,但如果您使用dis检查函数的字节码,您可以看到它们是以不同的方式构建的,即t1在定义时评估其默认参数,因此不需要在随后的函数调用中重新定义:

>>> import dis
>>> def t1(A=1):
...   pass
>>> def t2():
....  A=1
>>> dis.dis(t1)
2           0 LOAD_CONST               0 (None)
3 RETURN_VALUE        
>>> dis.dis(t2)
2           0 LOAD_CONST               1 (1)
3 STORE_FAST               0 (A)
6 LOAD_CONST               0 (None)
9 RETURN_VALUE        

最新更新