在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子。
functools 模块
如:
1. functools.cache
#python3.9 新增
@functools.cache(user_function)
返回值与 lru_cache(maxsize=None)
相同,创建一个查找函数参数的字典的简单包装器. 因为它不需要移出旧值,所以比带有大小限制的 lru_cache()
更小更快.
如,
from functools import cache
@cache
def factorial(n):
print(f"[Cache]计算 {n} 的阶乘")
return n * factorial(n-1) if n else 1
#没有缓存,计算11次递归调用
a = factorial(10)
#已有缓存,直接查询缓存结果
b = factorial(5)
#除了已有缓存,新增两次递归调用
c = factorial(12)
2. functools.lru_cache
一般用于缓存的内存空间是固定的,当有更多的数据需要缓存的时候,需要将已缓存的部分数据清除后再将新的缓存数据放进去。需要清除哪些数据,就涉及到了缓存置换的策略,其中,LRU(Least Recently Used,最近最少使用)是很常见的一个,也是 Python 中提供的缓存置换策略。
functools.lru_cache
函数是一个装饰器,为函数提供缓存功能。在下次以相同参数调用时直接返回上一次的结果,缓存 maxsize 组传入参数,用于节约高开销或I/O函数的调用时间.
@functools.lru_cache(maxsize=128, typed=False)
#若,maxsize=None,则LRU特性被禁用,且缓存可无线增长.
由于使用了字典存储缓存,所以该函数的固定参数和关键字参数必须是可哈希的。
被 lru_cache
修饰的函数在被相同参数调用的时候,后续的调用都是直接从缓存读结果,而不用真正执行函数。
from functools import lru_cache
def factorial(n):
print(f"[No LRU_Cache]计算 {n} 的阶乘")
return 1 if n <= 1 else n * factorial(n - 1)
@lru_cache
def factorial_lru(n):
print(f"[LRU_Cache]计算 {n} 的阶乘")
return 1 if n <= 1 else n * factorial_lru(n - 1)
#没有 LRU Cache,每次重新计算调用
a = factorial(5)
print(f'5! = {a}')
b = factorial(3)
print(f'3! = {b}')
#没有缓存,计算5次递归调用
a = factorial_lru(5)
print(f'5! = {a}')
#查看缓存信息
print(factorial_lru.cache_info())
#输出如:CacheInfo(hits=0, misses=5, maxsize=128, currsize=5)
#已有缓存,直接读取存储值
b = factorial_lru(3)
print(f'3! = {b}')
#清除缓存
factorial_lru.cache_clear()
print(factorial_lru.cache_info())
#输出如,CacheInfo(hits=0, misses=5, maxsize=128, currsize=5)
lru_cache缓存装饰器提供的功能有:
- 缓存被装饰对象的结果(基础功能)
- 获取缓存信息
- 清除缓存内容
- 根据参数变化缓存不同的结果
- LRU算法当缓存数量大于设置的maxsize时清除最不常使用的缓存结果