问题描述
尤其是,在使用递归代码时,lru_cache
进行了大量改进.我确实知道,缓存是一个空间,用于存储必须快速提供服务的数据,并且可以避免计算机被重新计算.
Especially when using recursive code there are massive improvements with lru_cache
. I do understand that a cache is a space that stores data that has to be served fast and saves the computer from recomputing.
functools中的 Python lru_cache
在内部如何工作?
How does the Python lru_cache
from functools work internally?
我正在寻找一个特定的答案,它是否像其他Python一样使用字典?它仅存储return
值吗?
I'm Looking for a specific answer, does it use dictionaries like the rest of Python? Does it only store the return
value?
我知道 Python 主要是建立在词典之上的,但是,我找不到这个问题的具体答案.希望有人可以为 StackOverflow 上的所有用户简化此答案.
I know that Python is heavily built on top of dictionaries, however, I couldn't find a specific answer to this question. Hopefully, someone can simplify this answer for all the users on StackOverflow.
推荐答案
functools的来源可在此处找到: https://github.com/python/cpython/blob/3.6/Lib/functools.py
Source of functools is available here: https://github.com/python/cpython/blob/3.6/Lib/functools.py
Lru_cache使用_lru_cache_wrapper
装饰器(带有参数模式的python装饰器),该装饰器在上下文中具有cache
字典 (每个装饰的函数都有自己的缓存字典),在其中保存被调用函数的返回值.字典键是根据参数使用_make_key
函数生成的.添加了一些粗体注释:
Lru_cache use _lru_cache_wrapper
decorator (python decorator with arguments pattern) which have cache
dictionary in context (every decorated function have own cache dict) where it saves return value of called function. Dictionary key is generated with _make_key
function according to arguments. Added some bold comments:
# ACCORDING TO PASSED maxsize ARGUMENT _lru_cache_wrapper
# DEFINES AND RETURNS ONE OF wrapper DECORATORS
def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
# Constants shared by all lru cache instances:
sentinel = object() # unique object used to signal cache misses
cache = {} # RESULTS SAVES HERE
cache_get = cache.get # bound method to lookup a key or return None
# ... maxsize is None:
def wrapper(*args, **kwds):
# Simple caching without ordering or size limit
nonlocal hits, misses
key = make_key(args, kwds, typed) # BUILD A KEY FROM ARGUMENTS
result = cache_get(key, sentinel) # TRYING TO GET PREVIOUS CALLS RESULT
if result is not sentinel: # ALREADY CALLED WITH PASSED ARGUMENTS
hits += 1
return result # RETURN SAVED RESULT
# WITHOUT ACTUALLY CALLING FUNCTION
result = user_function(*args, **kwds) # FUNCTION CALL - if cache[key] empty
cache[key] = result # SAVE RESULT
misses += 1
return result
# ...
return wrapper
这篇关于Lru_cache(来自functools)如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!