我尝试了一些测试:
import timeit
a = "hi"
def f():
return "hi"
def g():
return a
timeit.timeit("f()", globals={"f": f}, number=100000000)
# 6.028764325194061
timeit.timeit("g()", globals={"g": g, "a": a}, number=100000000)
# 6.053381357342005
正常版本和“缓存”版本之间似乎没有什么区别。为什么?也许默认情况下,Python会缓存在模块,函数和类中定义的不可变对象?
编辑:此外,还有一个奇怪的事实:代码
timeit.timeit("g()", globals={"g": g}, number=100000000)
没有给我任何错误。但是我没有将变量a
传递给timeit
,难道不应该给我一个例外吗?
答案 0 :(得分:0)
测量性能总是极其棘手,因为涉及许多层,从应用程序代码,运行时环境,所用的pthon解释器,操作系统到裸机(例如CPU缓存)。例如,看看SO question about loop performance。
如果我使用python 3.7.3在计算机上运行相同的测试,则会得到以下结果:
4.8285931999998866
5.371130099956645
所以我的情况相差〜10%。如果我再运行一次相同的测试几次,我还将得到以下结果:
4.646976499861921
5.513043400060269
现在,两种实现之间存在〜18%的差异。我可能会再进行几次相同的测试,像您一样得到<1%的差异。
简而言之:衡量性能差异真的很困难,不要轻易相信您的发现。
编辑:广告“奇怪的事实”:我认为您不需要将a
传递给timeit
,因为调用g()
确实可以无论如何都不访问传递的变量,而是在函数定义期间引用的变量。验证:以下代码不会引发异常:
a = 'hi'
def t():
if a == 'a':
raise Exception()
timeit.timeit("t()", globals={"t": t, "a": "a"}, number=1000000)