我尝试了一点测试:
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
,难道不应该给我一个例外吗?
测量性能总是极端棘手,因为涉及到许多层,从应用程序代码,运行时环境,所用的pthon解释器,操作系统到裸机(如CPU缓存)。例如,查看SO question about loop performance。
如果我使用python 3.7.3在计算机上运行相同的测试,则会得到以下结果:
4.8285931999998866
5.371130099956645
所以我的情况下相差〜10%。如果再运行一次相同的测试几次,我还将得到以下结果:
4.646976499861921
5.513043400060269
现在两个实现之间有一个[[〜18%差异。我可能会再运行几次相同的测试,并且像您一样得到<1%的差异。
简而言之:衡量性能差异非常困难,不要轻易相信您的发现。
EDIT
:广告“奇怪的事实”:我假设您不需要将a
传递给timeit
,因为调用g()
始终不会访问传递的变量,但是在函数定义期间引用。验证:以下代码不会引发异常:a = 'hi'
def t():
if a == 'a':
raise Exception()
timeit.timeit("t()", globals={"t": t, "a": "a"}, number=1000000)