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 方法称为1785times。现在,我的问题是我是否可以记住 newDict 方法以减少调用时间?(只是为了确保变量几乎在每次调用中都会发生变化,尽管我不确定它是否对记忆函数有影响)

子问题:我认为17k调用太多了,代码效率不高。但是通过查看统计数据,您是否也可以说明这是正常结果还是我有太多调用并且代码很慢?

4

3 回答 3

9
  1. 你的意思memoize不是memorize
  2. 如果值几乎总是不同的,记忆将无济于事,它会减慢速度。
  3. 如果没有看到你的完整代码,也不知道它应该做什么,我们怎么知道 17k 调用是多还是少?
于 2011-08-16T12:04:14.363 回答
8

如果通过记忆你的意思是记忆,使用functools.lru_cache. 这是一个函数装饰器

于 2011-08-16T12:01:12.537 回答
2

记忆的目的是保存执行成本高昂的操作的结果,以便可以为其提供第二次、第三次等时间,而不必重复操作并重复产生费用。

记忆化通常应用于(a)执行昂贵的操作,(b)在给定相同参数的情况下总是产生相同的结果,并且(c)对程序状态没有副作用的函数。

记忆通常在这样的函数中通过“保存”结果以及产生该结果的参数值来实现。这是缓存一般概念的一种特殊形式。每次调用该函数时,该函数都会检查其备忘录缓存以查看它是否已经确定了适合参数当前值的结果。如果缓存中包含结果,则无需重新计算即可返回。

您的函数似乎旨在在每次调用它时创建一个新的字典。似乎没有一种明智的方法来记忆这个函数:你总是希望一个新的字典返回给调用者,这样它对接收到的字典的使用就不会干扰对函数的其他调用。

我可以使用 memoizing 进行可视化的唯一方法是,如果 (1) 计算放入结果中的一个或多个值是昂贵的(在这种情况下,我可能会定义一个计算值并记忆该函数的函数)或( 2) newDict 函数旨在返回给定一组特定参数值的相同值集合。在后一种情况下,我不会使用字典,而是使用不可修改的对象(例如,像字典一样的类,但可以防止修改其内容)。

关于您的子问题,您需要问的问题是(1)是正确调用 newDict 的次数,(2)是否可以减少每次执行 newDict 的执行时间。这是两个独立的问题,需要酌情单独解决。

顺便说一句,您的函数定义中有一个错字——返回关键字和左大括号之间不应有“d”。

于 2012-10-09T17:18:22.803 回答