这篇关于记忆化的文章引起了我的好奇心。我做了自己的基准测试。
1)可变默认字典:
%%timeit
def fibo(n, dic={}) :
if n not in dic :
if n in (0,1) :
dic[n] = 1
else :
dic[n] = fibo(n-1)+fibo(n-2)
return dic[ n ]
fibo(30)
输出:
100000 loops, best of 3: 18.3 µs per loop
2) 相同的思路,但遵循“宁可道歉不要求许可”的原则:
In [21]:
%%timeit
def fibo(n, dic={}) :
try :
return dic[n]
except :
if n in (0,1) :
dic[n] = 1
else :
dic[n] = fibo(n-1)+fibo(n-2)
return dic[ n ]
fibo(30)
输出:
10000 loops, best of 3: 46.8 µs per loop
我的问题
- 为什么2)与1)相比速度如此之慢?
编辑
正如评论中@kevin所建议的那样,我完全弄错了装饰器,因此我将其删除。剩下的仍然有效!(希望是这样)
f
。当你装饰fibo
时,实际上是在做“丢弃此函数的定义,并用示例1中的函数替换它”的操作。 - Kevinhasattr
或if key in d:
的开销。此原则经常用于在尝试使用键/属性之前检查它们的存在,这更容易被原谅(有时候)。 - dano