为啥我的 LRU 缓存会丢失相同的参数?

Posted

技术标签:

【中文标题】为啥我的 LRU 缓存会丢失相同的参数?【英文标题】:Why does my LRU cache miss with the same argument?为什么我的 LRU 缓存会丢失相同的参数? 【发布时间】:2016-03-01 20:34:48 【问题描述】:

我有一些看起来像这样的代码:

from functools import lru_cache


@lru_cache()
def get_cheese(type):
    print('? We\'re all out.'.format(type))
    return None

get_cheese(type='cheddar')
get_cheese('cheddar')
print(get_cheese.cache_info())

cache_info() 报告有 两个 未命中 - 但我使用相同的参数调用了该函数。

实际上需要做一些事情,但我发现这是因为在一个实例中我使用了关键字 arg,而在另一个实例中我使用了位置参数。

但是为什么

【问题讨论】:

是的,缓存可能不是我的问题,但是处理缓存是我遇到这个问题的原因,所以我认为这可能是一个合理的标签...... 【参考方案1】:

functools.lru_cache 创建的包装器不会尝试检查或复制被包装函数的签名。 Python版本为defined as

def wrapper(*args, **kwargs):
    ...
    key = make_key(args, kwds, typed)
    ...

如您所见,它基于argskwargs 构建缓存中使用的键,而不知道任何位置或关键字参数是否等效。 C version 类似地构建密钥而不关心原始签名。

至于为什么要这样设计?我不知道最初的理由。这可能是经过深思熟虑的,要么是为了简化实现,要么是为了避免将关键字参数与位置匹配的开销,或者它可能是一个疏忽。如果您认为值得更改,可以在 issue tracker 上提出。

【讨论】:

有趣的是:关键字是sorted,所以无论您提供关键字的顺序是什么,您都可以这样做。我确实实际上考虑在问题跟踪器上提出它......但老实说,我认为这是正确的方法,它只需要更好的文档。我真的没有看到任何提及这种行为in the docs

以上是关于为啥我的 LRU 缓存会丢失相同的参数?的主要内容,如果未能解决你的问题,请参考以下文章

实现函数调用结果的 LRU 缓存

一日一技:实现函数调用结果的 LRU 缓存

python3_原生 LRU 缓存

java - LinkedHashMap 实现 LRU

Redis的缓存淘汰策略LRU与LFU

函数缓存 (Function caching)