简体   繁体   English

python 如何记忆一个方法

[英]python how to memoize a method

Say I a method to create a dictionary from the given parameters:假设我有一种从给定参数创建字典的方法:

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 }

And I have another method that calls newDict method each time it is executed.我还有另一种方法,每次执行时都会调用 newDict 方法。 Therefore, at the end, when I look at my cProfiler I see something like this:因此,最后,当我查看我的 cProfiler 时,我会看到如下内容:

17874 calls (17868 primitive) 0.076 CPU seconds

and of course, my newDict method is called 1785 times.当然,我的 newDict 方法被调用了1785次。 Now, my question is whether I can memorize the newDict method so that I reduce the call times?现在,我的问题是我是否可以记住 newDict 方法以减少调用时间? (Just to make sure, the variables change almost in every call, though I'm not sure if it has an effect on memorizing the function) (只是为了确保变量几乎在每次调用中都会发生变化,尽管我不确定它是否对记忆函数有影响)

Sub Question: I believe that 17k calls are too much, and the code is not efficient.子问题:我认为17k调用太多了,代码效率不高。 But by looking at the stats can you also please state whether this is a normal result or I have too many calls and the code is slow?但是通过查看统计数据,您是否也可以请 state 这是正常结果还是我有太多电话并且代码很慢?

  1. You mean memoize not memorize .你的意思是memoize不是memorize
  2. If the values are almost always different, memoizing won't help, it will slow things down.如果值几乎总是不同的,记忆将无济于事,它会减慢速度。
  3. Without seeing your full code, and knowing what it's supposed to do, how can we know if 17k calls is a lot or the little?如果没有看到你的完整代码,也不知道它应该做什么,我们怎么知道 17k 调用是多还是少?

If by memorizing you mean memoizing, use functools.lru_cache .如果通过记忆你的意思是记忆,使用functools.lru_cache It's a function decorator这是一个 function 装饰器

The purpose of memoizing is to save a result of an operation that was expensive to perform so that it can be provided a second, third, etc., time without having to repeat the operation and repeatedly incur the expense.记忆的目的是保存执行成本高昂的操作的结果,以便可以为其提供第二次、第三次等时间,而不必重复操作并重复产生费用。

Memoizing is normally applied to a function that (a) performs an expensive operation, (b) always produces the same result given the same arguments, and (c) has no side effects on the program state.记忆通常应用于 function,它 (a) 执行昂贵的操作,(b) 在相同的 arguments 下总是产生相同的结果,并且 (c) 对程序 Z9ED39E2EA931586B3A985A6942EZEF5 没有副作用。

Memoizing is typically implemented within such a function by 'saving' the result along with the values of the arguments that produced that result.记忆通常在这样的 function 中通过“保存”结果以及产生该结果的 arguments 的值来实现。 This is a special form of the general concept of a cache.这是缓存一般概念的一种特殊形式。 Each time the function is called, the function checks its memo cache to see if it has already determined the result that is appropriate for the current values of the arguments.每次调用 function 时,function 都会检查其备忘录缓存,以查看它是否已经确定了适合 arguments 的当前值的结果。 If the cache contains the result, it can be returned without the need to recompute it.如果缓存中包含结果,则无需重新计算即可返回。

Your function appears to be intended to create a new dict each time it is called.您的 function 似乎是为了在每次调用它时创建一个新的字典。 There does not appear to be a sensible way to memoize this function: you always want a new dict returned to the caller so that its use of the dict it receives does not interfere with some other call to the function.似乎没有一种明智的方式来记忆这个 function:您总是希望将一个新的字典返回给调用者,以便它使用它收到的字典不会干扰对 function 的其他调用。

The only way I can visualize using memoizing would be if (1) the computation of one or more of the values placed into the result are expensive (in which case I would probably define a function that computes the value and memoize that function) or (2) the newDict function is intended to return the same collection of values given a particular set of argument values.我可以使用 memoizing 进行可视化的唯一方法是(1)计算一个或多个放入结果中的值很昂贵(在这种情况下,我可能会定义一个 function 来计算值并记住该函数)或( 2) newDict function 旨在返回给定一组特定参数值的相同值集合。 In the latter case I would not use a dict but would instead use a non-modifiable object (eg, a class like a dict but with protections against modifying its contents).在后一种情况下,我不会使用字典,而是使用不可修改的 object (例如,像字典一样的 class ,但可以防止修改其内容)。

Regarding your subquestion, the questions you need to ask are (1) is the number of times newDict is being called appropriate and (2) can the execution time of each execution of newDict be reduced.关于您的子问题,您需要问的问题是(1)是正确调用 newDict 的次数,(2)是否可以减少每次执行 newDict 的执行时间。 These are two separate and independent questions that need to be individually addressed as appropriate.这是两个独立的问题,需要酌情单独解决。

BTW your function definition has a typo in it -- the return should not have a 'd' between the return keyword and the open brace.顺便说一句,您的 function 定义中有错字——返回关键字和左大括号之间不应有“d”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM