“缓存”字符串:为什么没有效果?

2024-03-29 08:20:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我做了个小测试:

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,不应该给我一个异常吗?你知道吗


Tags: 模块数据函数import版本编辑numberreturn
1条回答
网友
1楼 · 发布于 2024-03-29 08:20:57

衡量性能总是非常棘手的,因为涉及到很多层,从应用程序代码、运行时环境、使用的pthon解释器、操作系统到裸机(如CPU缓存)。例如,我们来看一下SO question about loop performance。你知道吗

如果使用python 3.7.3在我的机器上运行相同的测试,将得到以下结果:

4.8285931999998866
5.371130099956645

所以在我的情况下有10%的差别。如果我再运行几次相同的测试,也会得到以下结果:

4.646976499861921
5.513043400060269

现在这两种实现之间有18%的差异。我可能会多次运行相同的测试,并得到<;1%的差异,就像您所做的那样。你知道吗

简而言之:衡量绩效差异非常困难,不要轻易相信你的发现。你知道吗

编辑:ad“奇怪的事实”:我假设您不需要将a传递给timeit,因为调用g()无论如何都不会访问传递的变量,而是在函数定义期间引用的变量。验证:以下代码不会引发异常:

a = 'hi'
def t():
    if a == 'a':
        raise Exception()
timeit.timeit("t()", globals={"t": t, "a": "a"}, number=1000000)

相关问题 更多 >