在计算机软件领域,缓存(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时清除最不常使用的缓存结果
Last modification:January 24th, 2022 at 02:41 pm