一日一技:实现函数调用结果的 LRU 缓存

简介: 一日一技:实现函数调用结果的 LRU 缓存

摄影:产品经理

在工程项目中,可能有一些函数调用耗时很长,但是又需要反复多次调用,并且每次调用时,相同的参数得到的结果都是相同的。在这种情况下,我们可能会使用变量或者列表来存放,例如:

resp_1 = get_resp(param=1)
resp_2 = get_resp(param=2)
resp_3 = get_resp(param=3)

但是,如果返回的结果占用内存比较大,我们每次调用都把结果存在内存里面,就会消耗大量内存。

于是,我们可以使用 LRU 算法:最近最常使用的参数生成的结果,我们存下来,下次遇到相同的参数时直接返回结果。而不常出现的参数,等到需要的时候再计算。计算完成后,也先存下来。但是如果缓存空间不够了,不常使用的会先删除。

LRU 的算法自己手动实现起来比较麻烦,但好在 Python 的 functions模块已经提供了现成的 lru_cache装饰器供我们使用。

首先我们写一个不带 lru 算法的程序:

import time
import datetime
def say(name):
    print(f'你好:{name}')
    now = datetime.datetime.now()
    return now
now = say('kingname')
print(f'现在时间为:{now}')
time.sleep(10)
now = say('产品经理')
print(f'现在时间为:{now}')
time.sleep(10)
now = say('kingname')
print(f'现在时间为:{now}')

运行效果如下图所示:

从运行结果可以看到,调用函数三次,第一次和第三次传入的参数都是 kingname,第二次传入的参数为 产品经理你好:kingname打印了两次, 你会:产品经理打印了一次。第二次打印的时间比第一次多了10秒,第三次打印的时间比第二次多了10秒。

现在我们把 LRU 缓存加上。

import time
import datetime
from functools import lru_cache
@lru_cache(maxsize=32)
def say(name):
    print(f'你好:{name}')
    now = datetime.datetime.now()
    return now
now = say('kingname')
print(f'现在时间为:{now}')
time.sleep(10)
now = say('产品经理')
print(f'现在时间为:{now}')
time.sleep(10)
now = say('kingname')
print(f'现在时间为:{now}')

从打印出来的结果可以看出,第三次调用 say函数的时候,传入的也是 kingname,但是函数根本没有运行,所以没有打印第二个 你好:kingname。并且第三个时间与第一个时间完全相同。说明第三次调用函数的时候,直接读取的缓存。

lru_cache(maxsize=128,typed=False)接收两个参数,第一个参数 maxsize表示最多缓存多少个结果,这个数字建议设置为2的幂。超出这个结果就会启用 LRU 算法删除不常用的数据。第二个参数 typed表示是否检查参数类型,默认为 False,如果设置为 True,那么参数 33.0会被当做不同的数据处理。

由于 lru_cache底层是基于字典来实现的缓存,所以参数都必须是 hashable 的,否则会导致报错。

目录
相关文章
|
3月前
|
缓存 算法 数据挖掘
深入理解缓存更新策略:从LRU到LFU
【10月更文挑战第7天】 在本文中,我们将探讨计算机系统中缓存机制的核心——缓存更新策略。缓存是提高数据检索速度的关键技术之一,无论是在硬件还是软件层面都扮演着重要角色。我们会详细介绍最常用的两种缓存算法:最近最少使用(LRU)和最少使用频率(LFU),并讨论它们的优缺点及适用场景。通过对比分析,旨在帮助读者更好地理解如何选择和实现适合自己需求的缓存策略,从而优化系统性能。
76 3
|
3月前
|
缓存 分布式计算 NoSQL
大数据-47 Redis 缓存过期 淘汰删除策略 LRU LFU 基础概念
大数据-47 Redis 缓存过期 淘汰删除策略 LRU LFU 基础概念
88 2
|
5月前
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
246 1
|
6月前
|
缓存 Python
在Python中,`functools`模块提供了一个非常有用的装饰器`lru_cache()`,它实现了最近最少使用(Least Recently Used, LRU)缓存策略。
在Python中,`functools`模块提供了一个非常有用的装饰器`lru_cache()`,它实现了最近最少使用(Least Recently Used, LRU)缓存策略。
|
5月前
|
存储 缓存 Java
|
5月前
|
存储 缓存 算法
Python 从零开始实现一个简单的LRU缓存
Python 从零开始实现一个简单的LRU缓存
49 0
|
7月前
|
缓存 算法 索引
LeetCode146:LRU缓存
LeetCode146:LRU缓存
57 1
|
6月前
|
缓存 算法 前端开发
前端 JS 经典:LRU 缓存算法
前端 JS 经典:LRU 缓存算法
109 0
|
8月前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
8月前
|
缓存 算法 前端开发
前端开发者必知的缓存淘汰策略:LRU算法解析与实践
前端开发者必知的缓存淘汰策略:LRU算法解析与实践
237 0