lru_cache

lru_cache 是 Python 标准库 functools 模块中的一个装饰器,用于实现缓存功能。它通过缓存函数的返回值来提高函数的执行效率,特别是对于计算密集型函数或具有大量重复输入的函数。

lru_cache 的全称是 “Least Recently Used Cache”,即最近最少使用缓存。它使用一个字典来存储函数的返回值,字典的键是函数的参数,值是函数的返回值。当函数被调用时,lru_cache 会首先检查参数是否已经在缓存中,如果在,则直接返回缓存中的值;如果不在,则计算函数的返回值,并将结果存入缓存。

lru_cache 有一些可选参数,可以用来控制缓存的大小和过期时间。

1
2
3
4
5
6
7
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)

在上面的例子中,lru_cache 装饰器将 fibonacci 函数的返回值缓存起来,最多缓存 128 个结果。当 fibonacci 函数被调用时,lru_cache 会首先检查参数是否已经在缓存中,如果在,则直接返回缓存中的值;如果不在,则计算函数的返回值,并将结果存入缓存。

需要注意的是,lru_cache 只能缓存可哈希的参数。如果函数的参数是不可哈希的,如列表或字典,lru_cache 将无法缓存函数的返回值。

另外,lru_cache 不会自动清理缓存。如果缓存中的数据不再需要,需要手动清理缓存。可以使用 cache_clear() 方法来清空缓存。

1
fibonacci.cache_clear()

案例

lru_cache 可以用于各种场景,以下是一些常见的使用案例:

  1. 缓存函数结果

lru_cache 可以用于缓存函数的结果,避免重复计算。这在处理递归函数或计算密集型函数时特别有用。

1
2
3
4
5
6
7
8
9
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(30)) # 输出: 832040
  1. 优化性能

lru_cache 可以用于优化性能,特别是在处理大量重复输入的函数时。通过缓存函数的结果,可以避免重复计算,从而提高函数的执行效率。

1
2
3
4
5
6
7
8
from functools import lru_cache

@lru_cache(maxsize=128)
def heavy_computation(n):
# 模拟一个计算密集型函数
return sum(range(n))

print(heavy_computation(1000000)) # 输出: 499999500000
  1. 限制缓存大小

lru_cachemaxsize 参数可以用于限制缓存的大小。当缓存满了之后,lru_cache 会自动删除最近最少使用的缓存项。

1
2
3
4
5
6
7
8
9
10
11
from functools import lru_cache

@lru_cache(maxsize=3)
def heavy_computation(n):
# 模拟一个计算密集型函数
return sum(range(n))

print(heavy_computation(1000000)) # 输出: 499999500000
print(heavy_computation(2000000)) # 输出: 1999999000000
print(heavy_computation(3000000)) # 输出: 2999999000000
print(heavy_computation(4000000)) # 输出: 3999999000000

在上面的例子中,lru_cachemaxsize 参数被设置为 3,所以最多只能缓存 3 个结果。当第 4 个结果被计算出来时,lru_cache 会自动删除最近最少使用的缓存项。

  1. 缓存过期lru_cache 还可以用于实现缓存过期。通过设置 typed 参数为 Truelru_cache 会将缓存项的类型作为键的一部分,从而实现缓存过期。
1
2
3
4
5
6
7
8
9
10
from functools import lru_cache

@lru_cache(typed=True)
def heavy_computation(n):
# 模拟一个计算密集型函数
return sum(range(n))

print(heavy_computation(1000000)) # 输出: 499999500000
print(heavy_computation(1000000)) # 输出: 499999500000
print(heavy_computation(2000000)) # 输出: 1999999000000

在上面的例子中,lru_cachetyped 参数被设置为 True,所以 heavy_computation 函数的结果会被缓存两次,一次是 n 为 1000000,一次是 n 为 2000000。当 n 为 1000000 时,lru_cache 会返回缓存中的结果;当 n 为 2000000 时,lru_cache 会重新计算结果,并将结果存入缓存。

总结起来,lru_cache 是一个非常有用的装饰器,可以帮助我们提高函数的执行效率,特别是在处理大量重复输入或计算密集型函数时。