我刚开始学习Python,我不知道什么是内存化,也不知道如何使用它。另外,我可以举一个简单的例子吗?


当前回答

记忆是保留昂贵的计算结果并返回缓存的结果,而不是不断地重新计算它。

这里有一个例子:

def doSomeExpensiveCalculation(self, input):
    if input not in self.cache:
        <do expensive calculation>
        self.cache[input] = result
    return self.cache[input]

更完整的描述可以在维基百科关于记忆的条目中找到。

其他回答

只是想对已经提供的答案进行补充,Python装饰器库有一些简单但有用的实现,也可以记住“不可哈希类型”,不像functools.lru_cache。

其他答案很好地涵盖了它的本质。我不是在重复。只是一些可能对你有用的观点。

通常,memoisation是一种可以应用在任何函数上的操作,该函数计算一些东西(昂贵的)并返回一个值。因此,它通常被实现为一个装饰器。实现很简单,大概是这样的

memoised_function = memoise(actual_function)

或者表示为装饰者

@memoise
def actual_function(arg1, arg2):
   #body

如果要考虑速度:

@functools。cache和@functools.lru_cache(maxsize=None)同样快,在我的系统上循环一百万次需要0.122秒(最好运行15次) 全局缓存变量要慢得多,在我的系统上循环一百万次需要0.180秒(最好运行15次) 一个自我。缓存类变量仍然有点慢,在我的系统上循环一百万次需要0.214秒(最好运行15次)

后两者的实现方式与目前投票最多的答案中描述的类似。

这没有防止内存耗尽,也就是说,我没有在类或全局方法中添加代码来限制缓存的大小,这真的是最基本的实现。如果需要的话,lru_cache方法可以免费提供。

对我来说,一个悬而未决的问题是如何对具有functools装饰器的东西进行单元测试。是否有可能以某种方式清空缓存?单元测试似乎使用class方法(在这里您可以为每个测试实例化一个新类)或全局变量方法(因为您可以使用您的rimportedmodule)是最干净的。Cachevariable ={}来清空它)。

记忆是保留昂贵的计算结果并返回缓存的结果,而不是不断地重新计算它。

这里有一个例子:

def doSomeExpensiveCalculation(self, input):
    if input not in self.cache:
        <do expensive calculation>
        self.cache[input] = result
    return self.cache[input]

更完整的描述可以在维基百科关于记忆的条目中找到。

与传递关键字参数的顺序无关的位置参数和关键字参数的解决方案(使用inspect.getargspec):

import inspect
import functools

def memoize(fn):
    cache = fn.cache = {}
    @functools.wraps(fn)
    def memoizer(*args, **kwargs):
        kwargs.update(dict(zip(inspect.getargspec(fn).args, args)))
        key = tuple(kwargs.get(k, None) for k in inspect.getargspec(fn).args)
        if key not in cache:
            cache[key] = fn(**kwargs)
        return cache[key]
    return memoizer

类似的问题:在Python中识别用于内存化的等效可变参数函数调用