当前位置: 首页 > news >正文

LRU (Least Recently Used) 缓存实现及原理讲解

LRU (Least Recently Used) 是一种常见的缓存淘汰策略,它会优先淘汰最近最少使用的数据。下面我将用JavaScript实现一个LRU类,并详细讲解其原理。

LRU实现

class LRUCache {constructor(capacity) {this.capacity = capacity; // 缓存容量this.cache = new Map(); // 使用Map存储键值对}get(key) {if (!this.cache.has(key)) {return -1; // 如果键不存在,返回-1}// 获取值const value = this.cache.get(key);// 删除旧的键值对this.cache.delete(key);// 重新设置键值对,这样它会位于Map的末尾(表示最近使用)this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) {// 如果键已存在,先删除旧的this.cache.delete(key);} else if (this.cache.size >= this.capacity) {// 如果缓存已满,删除最久未使用的键(Map的第一个键)// Map.keys()返回一个迭代器,next().value获取第一个键const oldestKey = this.cache.keys().next().value;this.cache.delete(oldestKey);}// 设置新的键值对this.cache.set(key, value);}
}

使用示例

const lru = new LRUCache(2); // 容量为2lru.put(1, 1); // 缓存是 {1=1}
lru.put(2, 2); // 缓存是 {1=1, 2=2}
console.log(lru.get(1));    // 返回 1
lru.put(3, 3); // 该操作会使得键2作废,缓存是 {1=1, 3=3}
console.log(lru.get(2));    // 返回 -1 (未找到)
lru.put(4, 4); // 该操作会使得键1作废,缓存是 {4=4, 3=3}
console.log(lru.get(1));    // 返回 -1 (未找到)
console.log(lru.get(3));    // 返回 3
console.log(lru.get(4));    // 返回 4

原理讲解

1. 数据结构选择

我们使用JavaScript的Map对象来实现LRU缓存,因为:

  • Map保持了键值对的插入顺序

  • Map的查找、插入和删除操作都是O(1)时间复杂度

  • Map可以直接获取第一个键(最久未使用)和最后一个键(最近使用)

2. 核心思想

LRU的核心思想是"最近最少使用":

  • 当访问一个键时,将它移动到"最近使用"的位置(Map的末尾)

  • 当插入新键且缓存已满时,淘汰"最久未使用"的键(Map的第一个键)

3. 操作细节

get(key)操作:

  1. 检查键是否存在

  2. 如果存在,先删除该键值对,再重新插入(这样它会位于Map末尾)

  3. 返回对应的值

put(key, value)操作:

  1. 检查键是否已存在

    • 如果存在,先删除旧的键值对

  2. 如果键不存在且缓存已满,删除最久未使用的键(Map的第一个键)

  3. 插入新的键值对(这会自动放在Map末尾)

4. 时间复杂度

  • get操作:O(1) - Map的查找和删除操作都是O(1)

  • put操作:O(1) - Map的查找、删除和插入操作都是O(1)

5. 为什么Map保持顺序

在JavaScript中,Map对象会记住键值对的原始插入顺序。当我们迭代Map时,键值对会按照插入顺序返回。这使得我们可以利用这个特性来实现LRU策略:

  • 最近访问的键会被移动到Map末尾

  • 最久未访问的键自然就位于Map开头

变体与优化

对于更复杂的场景,可以考虑:

  1. 使用双向链表+哈希表实现(更高效的内存管理)

  2. 实现TTL(Time To Live)过期机制

  3. 添加统计功能,记录缓存命中率

这个实现简洁明了地展示了LRU的核心思想,适合大多数前端应用场景。如果需要更高性能的实现,可以考虑更复杂的数据结构组合。

http://www.lryc.cn/news/605163.html

相关文章:

  • Python读取获取波形图波谷/波峰
  • PSO-TCN-BiLSTM-MATT粒子群优化算法优化时间卷积神经网络-双向长短期记忆神经网络融合多头注意力机制多特征分类预测/故障诊断Matlab实现
  • Undo、Redo、Binlog的相爱相杀
  • 2025年华为HCIA-AI认证是否值得考?还是直接冲击HCIP?
  • 鸿蒙(HarmonyOS)模拟(Mock)数据技术
  • NestJS CLI入门
  • HPCtoolkit的下载使用
  • 7.Origin2021如何绘制拟合数据图?
  • 网络安全学习第16集(cdn知识点)
  • python 中 `batch.iloc[i]` 是什么:integer location
  • 【MySQL 数据库】MySQL索引特性(一)磁盘存储定位扇区InnoDB页
  • NEG指令说明
  • Android补全计划 TextView设置文字不同字体和颜色
  • 全视通智慧护理巡视:做护理人员的AI助手
  • 关于vue __VUE_HMR_RUNTIME__ is not defined报错处理
  • plex客户端升级以后显示的内容太多了怎么办?
  • 比特币挖矿的能源消耗和环保问题
  • 【图像处理】直方图均衡化c++实现
  • 个人如何做股指期货?
  • 以ros的docker镜像为例,探讨docker镜像的使用
  • Docker常用命令速查手册:容器运维七维指南
  • 深入剖析 Spark Shuffle 机制:从原理到实战优化
  • STL:序列式容器
  • 轻松打造Unity小游戏AR体验
  • PHP语法高级篇(七):MySQL数据库
  • OSS-服务端签名Web端直传+STS获取临时凭证+POST签名v4版本开发过程中的细节
  • Spring AOP详细解析
  • [硬件电路-106]:模拟电路 - 电路为什么会出现不同的频率特性?元件频率依赖性、信号传输路径、电路拓扑结构、外部因素
  • 【maven】仓库配置
  • Matrix Theory study notes[6]