python - "Caching"字符串 : why has no effect?

标签 python python-3.x micro-optimization

我尝试了一些测试:

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% 的差异,就像您一样。

简而言之:衡量性能差异确实很难,不要轻易相信您的发现。

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

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

关于python - "Caching"字符串 : why has no effect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58429590/

相关文章:

python - 类型错误 : KMeans() got an unexpected keyword argument 'n_clusters'

python - 多元回归的高斯总和

python - 类的最大递归深度

c# - DateTime.DayOfWeek 微优化

python - 哪个扩展性更好? ORM 的 distinct() 或 python set()

使用互斥组时的Python argparse AssertionError

python - 字符串切片和操作

Python lambda 不记得 for 循环中的参数

performance - x86 Assembly pushad/popad,它有多快?

performance - MIPS(好奇心)清除寄存器的更快方法?