Python 为什么max()函数在比较两个元素时比直接比较if语句慢得多?
通过运行下面的代码,我可以直接与if语句进行比较,速度几乎是max函数的4倍 我试图理解这背后的原因 比较:0.63s,最大值:2.3sPython 为什么max()函数在比较两个元素时比直接比较if语句慢得多?,python,max,Python,Max,通过运行下面的代码,我可以直接与if语句进行比较,速度几乎是max函数的4倍 我试图理解这背后的原因 比较:0.63s,最大值:2.3s import time if _name_ == '_main_': sim = 10**7 s = time.time() for _ in range(sim): if 1 > 2: pass res1 = time.time()-s s = time.time()
import time
if _name_ == '_main_':
sim = 10**7
s = time.time()
for _ in range(sim):
if 1 > 2:
pass
res1 = time.time()-s
s = time.time()
for _ in range(sim):
max(1, 2)
res2 = time.time()-s
print('comparison : {:.2}s, max : {:.2}s'.format(res1, res2))
因为
max
涉及函数名的字典查找,然后是函数调用,而直接实际上是两个字典查找;一个在模块globals中,当失败时,另一个在内置范围中。如果在给定函数中多次调用max
,缓存它(例如,通过一个只包含关键字的参数,ladef myfunc(arg1,arg2,*,max=max):
)是一种廉价的方法,可以消除查找成本(用LOAD\u FAST
中的单个C数组索引操作替换LOAD\u GLOBAL
的两个dict
查找). 函数调用开销是更大的成本(通用函数分派的开销要比专门的时隙函数直接进行的开销大得多,例如,是的,字典查找是O(1)
。不过感谢精确性,很有意思。嗯,基本上都是O(1)
(除了“传递给max
)的项目数。dict
查找为O(1)
一般情况下,但恒定开销高于数组,并且在找到正确的项之前经常会发生一到两个bucket冲突。在我的机器上,一个加载但不调用max
1000次的函数在参数中没有缓存的情况下运行大约需要45μs,使用max=max
缓存的情况下运行大约需要25.5μs,21.5μs,如果1000长的循环体是pass
而不是max
。因此从本地1000x加载成本约为4μs,从内置范围加载成本约为23.5μs,开销几乎高出6倍。尽管如我所说,与实际调用它(让它调用max(1,2))相比,这种开销显得微不足道
将未缓存的时间增加到206μs,173μs,因此缓存的好处与调用函数的开销相比相形见绌)。现在我的答案似乎没有记录在案:)而且O(1)
并不意味着超长函数名的成本不高,因为哈希运算需要更长的计算时间(但对于max
,情况并非如此)。如果您想提高速度,可以使用编译语言,或者像numpy或pandas这样的框架,在其中传递大量数据的一个请求,而不是小请求。