python内置LRU缓存

python标准模块functools模块中的lru_cache装饰器实现了LRU缓存算法。

1. 什么是LRU缓存

在软件或系统开发中,缓存总是必不可少,这是一种空间换时间的技术,通过将频繁访问的数据缓存起来,下一次访问时就可以快速获得期望的结果。

一个缓存系统,关键核心的指标就是缓存命中率,如果命中率很低,那么这个缓存除了浪费了空间,对性能的提升毫无帮助。

LRU是一种常用的缓存算法,即最近最少使用,如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小, LRU算法选择将最近最少使用的数据淘汰,保留那些经常被命中的数据。

2. functools.lru_cache

从python 3.2开始,就已经将LRU作为标准库的一部分发布,functools模块中的lru_cache装饰器实现了LRU缓存算法。以计算斐波那契数列为例,对比有缓存的算法效率和无缓存的算法效率

import time
from functools import lru_cache


@lru_cache()        # 测试无缓存时将本行注释掉
def fib_memoization(number: int) -> int:
    if number == 0: return 0
    if number == 1: return 1

    return fib_memoization(number-1) + fib_memoization(number-2)

start = time.time()
res = fib_memoization(33)
print(res)
print(f'耗时: {time.time() - start}s')

在有缓存的情况下,计算33的斐波那契数列耗时仅为0.00008秒,去掉装饰器后,耗时则为2.9秒,可谓天差地别。不过要强调一点,之所以有如此巨大的性能差距,只要原因是由于斐波那契算法的特殊性导致的。

3. functools.lru_cache参数说明

lru_cache装饰器定义如下

def lru_cache(maxsize=128, typed=False):
    pass

只有连个参数,第一个参数规定缓存的数量,第二个参数如果设置为True,则严格检查被装饰函数的参数类型,默认为False

from functools import lru_cache

@lru_cache(typed=False)
def add(x, y):
    print('add')
    return x + y


print(add(3, 4))
print(add(3, 4.0))

第二次调用add函数时参数是4.0, 如果你认为这种情况可以使用缓存命中上一次3+4的结果,就将typed设置为False,如果你严格要求只有函数的参数完全一致时才能命中,那么将typed设置为True

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案