首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@lru_cache装饰器过多的缓存丢失

@lru_cache装饰器过多的缓存丢失
EN

Stack Overflow用户
提问于 2020-12-17 22:14:27
回答 1查看 419关注 0票数 4

如何配置lru_cache,以根据实际接收的值,而不是如何调用函数,来键入其缓存?

代码语言:javascript
复制
>>> from functools import lru_cache
>>> @lru_cache
... def f(x=2):
...     print("reticulating splines...")
...     return x ** 2
...
>>> f()
reticulating splines...
4
>>> f(2)
reticulating splines...
4
>>> f(x=2)
reticulating splines...
4

换句话说,上面的第一个调用应该是缓存丢失,另外两个应该是缓存命中。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-17 22:32:30

要做到这一点,您必须经历将参数绑定到形式参数的过程。这样做的实际过程是在没有公共接口的C代码中实现的,但是在inspect中有一个(慢得多的)重新实现。这比正常使用functools.lru_cache慢了大约100倍:

代码语言:javascript
复制
import functools
import inspect

def mycache(f=None, /, **kwargs):
    def inner(f):
        sig = inspect.signature(f)
        f = functools.lru_cache(**kwargs)(f)
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            bound = sig.bind(*args, **kwargs)
            bound.apply_defaults()
            return f(*bound.args, **bound.kwargs)
        return wrapper
    if f:
        return inner(f)
    return inner

@mycache
def f(x):
    print("reticulating splines...")
    return x ** 2

如果这种方法的性能损失太大,您可以使用以下技巧,它需要更多的代码复制,但运行速度要快得多,仅比通常使用lru_cache慢约2倍(有时使用关键字参数,速度更快):

代码语言:javascript
复制
@functools.lru_cache
def _f(x):
    print("reticulating splines...")
    return x ** 2

def f(x=2):
    return _f(x)

这使用更快的C级参数绑定来规范对回忆录助手函数的调用,但需要重复函数的参数3次:一次在外部函数的签名中,一次在助手的签名中,一次在对助手的调用中。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65349076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档