【发布时间】:2014-10-18 14:11:18
【问题描述】:
所以这个关于记忆的page 让我很好奇。我运行了自己的基准测试。
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 在 cmets 中建议的那样,我把装饰器弄错了,所以我把它删除了。其余的仍然有效! (希望)
【问题讨论】:
-
这是一个非常不寻常的装饰器。通常当你在装饰器的某个地方装饰一个函数时,你最终会在完成一些工作后调用该函数。但是你的装饰者从不打电话给
f。当您装饰fibo时,您实际上是在“丢弃此函数的定义,并将其替换为示例 1 中的函数” -
捕获异常(这意味着堆栈跟踪)可能非常昂贵:docs.python.org/2/faq/design.html#how-fast-are-exceptions
-
@DmitryBychenko 我认为您应该将其发布为答案。
-
“请求原谅比许可更容易”的原则从何而来? :0 在编程环境中这听起来相当不合理。
-
@BartoszKP 这是真的。大多数时候,用户可能会给你正确的东西。这就是为什么最好假设他们给了你正确的东西,如果它错了就处理异常。这样您就可以避免
hasattr或if key in d:的开销。该原则经常使用的另一个领域是在尝试使用键/属性之前检查它们是否存在,这(有时)更可能被实际原谅。
标签: python fibonacci memoization python-decorators