gpt4 book ai didi

python - @lru_cache 装饰器过多的缓存未命中

转载 作者:行者123 更新时间:2023-12-03 21:08:51 24 4
gpt4 key购买 nike

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

>>> 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
换句话说,只有上面的第一个调用应该是缓存未命中,其他两个应该是缓存命中。

最佳答案

为此,您必须完成将参数绑定(bind)到形式参数的过程。这样做的实际过程是在没有公共(public)接口(interface)的 C 代码中实现的,但是在 inspect 中有一个(慢得多的)重新实现。 .这比使用 functools.lru_cache 慢大约 100 倍。一般:

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 倍通常(有时更快,使用关键字参数):
@functools.lru_cache
def _f(x):
print("reticulating splines...")
return x ** 2

def f(x=2):
return _f(x)
这使用更快的 C 级参数绑定(bind)来规范对记忆化辅助函数的调用,但需要将函数的参数复制 3 次:一次在外部函数的签名中,一次在辅助函数的签名中,一次在对辅助函数的调用中.

关于python - @lru_cache 装饰器过多的缓存未命中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65349076/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com