““缓存”一个字符串:为什么无效?

问题描述 投票:0回答:1

我尝试了一点测试:

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,难道不应该给我一个例外吗?

python python-3.x micro-optimization
1个回答
0
投票

测量性能总是极端棘手,因为涉及到许多层,从应用程序代码,运行时环境,所用的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)
© www.soinside.com 2019 - 2024. All rights reserved.