为什么我的 LRU 缓存未命中相同的参数?
Why does my LRU cache miss with the same argument?
我有一些代码如下所示:
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,而另一个我使用了位置参数。
但是为什么?
functools.lru_cache
创建的包装器不会尝试检查或复制包装函数的签名。 Python 版本是 defined as
def wrapper(*args, **kwargs):
...
key = make_key(args, kwds, typed)
...
如您所见,它基于 args
和 kwargs
构建缓存中使用的键,而不知道任何位置参数或关键字参数是否等效。 C version 同样在不关心原始签名的情况下构建密钥。
至于为什么要这样设计?我不知道原来的理由。它可能是故意的,要么是为了简化实现,要么是为了避免将关键字参数与位置参数匹配的开销,或者它可能是一个疏忽。如果您认为改变它是值得的,您可以在 issue tracker.
上提出它
我有一些代码如下所示:
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,而另一个我使用了位置参数。
但是为什么?
functools.lru_cache
创建的包装器不会尝试检查或复制包装函数的签名。 Python 版本是 defined as
def wrapper(*args, **kwargs):
...
key = make_key(args, kwds, typed)
...
如您所见,它基于 args
和 kwargs
构建缓存中使用的键,而不知道任何位置参数或关键字参数是否等效。 C version 同样在不关心原始签名的情况下构建密钥。
至于为什么要这样设计?我不知道原来的理由。它可能是故意的,要么是为了简化实现,要么是为了避免将关键字参数与位置参数匹配的开销,或者它可能是一个疏忽。如果您认为改变它是值得的,您可以在 issue tracker.
上提出它