进行动态编程时,我使用装饰器保存中间结果。当我自己实现装饰器时,我发现返回的函数名称必须与传入的函数名称相同,这样会更快,但是我不知道为什么。这样的代码,如果我写r = memo(r)和r(300)运行非常快;但是如果我写fun = memo(r),则fun(300)运行缓慢。 我想知道装饰器的工作原理,谢谢。
def memo(func):
coach={}
def _w(n):
if n in coach:
result = coach[n]
else:
result = func(n)
coach[n]=result
return result
return _w
def r(n):
sub_price,sub_split = max(
[(price[n],n)]+[(r(i)+r(n-i),i) for i in range(1,n)],
key = lambda x:x[0])
if n not in solution:
solution[n] = (sub_split,n-sub_split)
#print(n," ",sub_split," ",n-sub_split," ",sub_price)
return sub_price
r = memo(r) fun = memo(r)
r(300) fun(300)#very slow
# fast
#this speed just like
#@memo
#def r( )
答案 0 :(得分:1)
fun = memo(r)
这很慢,因为此处r
仍指该函数的原始非存储版本,因此,r
调用自身时不会通过查找表,因此您具有相同的复杂度就像没有记忆。在这里,仅当您使用相同的参数多次调用fun
时,备忘录才有所不同。 r
的递归调用不受影响。
重新分配r
时,这也会影响递归调用,因此实际上您会更改函数的复杂性。