827*_*827 10 python memoization dynamic-programming
Is it "good practice" to create a class like the one below that can handle the memoization process for you? The benefits of memoization are so great (in some cases, like this one, where it drops from 501003 to 1507 function calls and from 1.409 to 0.006 seconds of CPU time on my computer) that it seems a class like this would be useful.
However, I've read only negative comments on the usage of eval(). Is this usage of it excusable, given the flexibility this approach offers?
这可以自动保存任何返回值,但会以丢失副作用为代价.谢谢.
import cProfile
class Memoizer(object):
"""A handler for saving function results."""
def __init__(self):
self.memos = dict()
def memo(self, string):
if string in self.memos:
return self.memos[string]
else:
self.memos[string] = eval(string)
self.memo(string)
def factorial(n):
assert type(n) == int
if n == 1:
return 1
else:
return n * factorial(n-1)
# find the factorial of num
num = 500
# this many times
times = 1000
def factorialTwice():
factorial(num)
for x in xrange(0, times):
factorial(num)
return factorial(num)
def memoizedFactorial():
handler = Memoizer()
for x in xrange(0, times):
handler.memo("factorial(%d)" % num)
return handler.memo("factorial(%d)" % num)
cProfile.run('factorialTwice()')
cProfile.run('memoizedFactorial()')
Run Code Online (Sandbox Code Playgroud)
MAK*_*MAK 14
你可以记住而不必诉诸eval.
一个(非常基本的)记忆器:
def memoized(f):
cache={}
def ret(*args):
if args in cache:
return cache[args]
else:
answer=f(*args)
cache[args]=answer
return answer
return ret
@memoized
def fibonacci(n):
if n==0 or n==1:
return 1
else:
return fibonacci(n-1)+fibonacci(n-2)
print fibonacci(100)
Run Code Online (Sandbox Code Playgroud)
eval 是经常拼错的evil,主要是因为在运行时执行"串"的想法充满了安全方面的考虑.你有足够的逃脱代码吗?引号?还有许多其他烦人的头痛.你的memoise处理程序有效,但它实际上不是Python的做事方式.MAK的方法更像是Pythonic.我们来试试吧.
我编辑了两个版本并使它们只运行一次,输入为100.我也搬出了实例Memoizer.结果如下.
>>> timeit.timeit(memoizedFactorial,number=1000)
0.08526921272277832h
>>> timeit.timeit(foo0.mfactorial,number=1000)
0.000804901123046875
Run Code Online (Sandbox Code Playgroud)
除此之外,你的版本需要一个包含要记忆的函数的包装器,它应该用字符串写.那很难看.MAK的解决方案很简洁,因为"记忆过程"被封装在一个单独的功能中,可以以不引人注目的方式方便地应用于任何昂贵的功能.这不是非常Pythonic.我在http://nibrahim.net.in/self-defence/的 Python教程中编写了这些装饰器的一些细节,以防你感兴趣.
| 归档时间: |
|
| 查看次数: |
1066 次 |
| 最近记录: |