如何在Python中对一个方法进行记忆化

3

假设我有一个方法,可以从给定的参数创建一个字典:

def newDict(a,b,c,d): # in reality this method is a bit more complex, I've just shortened for the sake of simplicity
    return { "x": a,
             "y": b,
             "z": c,
             "t": d }

我还有另一种方法,每次执行时都会调用newDict方法。因此,最终当我查看我的cProfiler时,会看到类似于这样的结果:

17874 calls (17868 primitive) 0.076 CPU seconds

当然,我的newDict方法被调用了1785次。现在,我的问题是是否可以记忆化newDict方法以减少调用次数?(只是为了确保,尽管我不确定它是否对记忆化函数产生影响,但变量几乎在每次调用中都会改变。)
子问题:我认为17k次调用太多了,代码效率不高。但是通过查看统计数据,您能否也请说明这是否是正常结果,或者我调用次数过多,代码运行缓慢?

以下Python配方中的memoize装饰器:http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ 对我很有帮助。 - Elias Dorneles
3个回答

9
  1. 你的意思是 memoize 而不是 memorize
  2. 如果值几乎总是不同,记忆化并不能帮助,反而会减慢速度。
  3. 如果没有看到完整的代码,也不知道它应该做什么,我们怎么知道17k次调用是多还是少呢?

8
如果你说的是记忆化,那么可以使用 functools.lru_cache。这是一个函数修饰器。

2
很遗憾,2.x版本中不可用。 - balki
2.x: https://pypi.org/project/backports.functools-lru-cache/ - frnhr

2
记忆化的目的是为了保存执行代价高昂的操作的结果,以便在不重复执行操作并重复承担代价的情况下,可以提供第二次、第三次等等。通常将记忆化应用于满足以下条件的函数:(a)执行昂贵的操作,(b)给定相同的参数始终产生相同的结果,(c)对程序状态没有副作用。通常在此类函数中实现记忆化的方法是将结果与产生该结果的参数值一起“保存”。这是缓存概念的一种特殊形式。每次调用函数时,函数都会检查其备忘录缓存,以查看它是否已经确定了适合当前参数值的结果。如果缓存包含结果,则可以返回结果而无需重新计算。
您的函数似乎旨在每次调用时创建一个新字典。似乎没有明智的方法来进行记忆化:您总是希望向调用者返回一个新字典,以使其接收到的字典使用不会干扰对函数的其他调用。
我唯一能想象使用记忆化的方式是:(1)放入结果的一个或多个值的计算代价很高(在这种情况下,我可能会定义一个计算值并记忆化该函数的函数),或者(2)newDict函数旨在返回给定一组参数值的相同值集合。在后一种情况下,我不会使用字典,而是会使用不可修改的对象(例如,类似字典但具有防止修改其内容的保护的类)。
关于您的子问题,您需要问的问题是:(1)newDict被调用的次数是否适当,(2)每次执行newDict的执行时间是否可以缩短。这些是需要分别适当地解决的两个独立的问题。
顺便说一句,您的函数定义中有一个拼写错误--返回应该没有在关键字return和左大括号之间加上'd'。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接