lru 淘汰算法
lru算法
计算机的内存缓存是有限的,在缓存满了就需要淘汰一部分数据,LRU 算法就是一种常用的淘汰旧数据的算法,LRU 算法的全称是 Least Recently Used,按照最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来,而最近频繁使用的数据会留在缓存中。核心思想 如果数据最近有被访问过,那么将来被访问的几率也更高 。 redis 和 mysql 都有使用 LRU 算法来淘汰冷数据。
LRU 会把所有的数据组织成一个链表。每当有新的数据就插入到链表的头部,当链表中的数据被访问,就把数据移动到链表头部,如果链表满了,就从链表末尾开始淘汰。
C# 实现,LinkedList 作为双向链表删除和插入效率都高,但是查找起来就需要遍历,操作的时间复杂度为 O(n),可以使用一个 Dictionary 来记录 key 在链表中的位置。
public class LruCache
{
private LinkedList<KeyValuePair<int, string>> _list;
private Dictionary<int, LinkedListNode<KeyValuePair<int, string>>> _map;
private int _capacity;
public LruCache(int capacity)
{
_capacity = capacity;
_list = new LinkedList<KeyValuePair<int, string>>();
_map = new Dictionary<int, LinkedListNode<KeyValuePair<int, string>>>();
}
/// <summary>
/// 获取值,如果值存在就把当前值的移动到链表首部。
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string Get(int key)
{
if (!_map.ContainsKey(key)) return string.Empty;
var item = _map[key];
_list.Remove(item);
_map[key] = _list.AddFirst(item.Value);
return item.Value.Value;
}
public void Put(int key, string value)
{
if (_map.ContainsKey(key))
{
// key存在更新值,并且移到首部。
var item = _map[key];
_list.Remove(item);
_map[key] = _list.AddFirst(new KeyValuePair<int, string>(key, value));
}
else
{
// key不存在,判断是否链表还有空间。
if (_list.Count >= _capacity)
{
// 淘汰末尾key
_map.Remove(_list.Last.Value.Key);
_list.RemoveLast();
}
_map[key] = _list.AddFirst(new KeyValuePair<int, string>(key, value));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了