左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。
公众号:一点sir,关注领取编程资料
LRU算法简介
LRU(Least Recently Used)算法是一种常用的缓存替换策略,用于在缓存空间有限的情况下,决定哪些数据应该保留在缓存中,哪些应该被替换掉。LRU算法的核心思想是:如果数据最近被访问过,那么将来被访问的几率也更高。因此,当缓存满时,应该替换掉最长时间未被使用的数据。
LRU算法的实现
LRU算法通常可以通过一个哈希表(用于快速定位缓存项)和一个双向链表(用于记录访问顺序)来实现。当缓存操作发生时,LRU算法的行为如下:
-
访问缓存:如果数据在缓存中,更新该数据在双向链表中的位置,将其移动到链表的头部(表示最近被访问)。
-
缓存未命中:如果数据不在缓存中,则从主存或其他存储中加载数据,并将其放入缓存链表的头部。
-
替换数据:当缓存满时,移除双向链表尾部的数据(表示最久未使用),并将新数据插入到链表头部。
具体说明
假设我们有一个固定大小为3的LRU缓存,现在按照以下顺序访问数据:
访问顺序: 1 -> 2 -> 3 -> 1 -> 4 -> 1
下面是每一步的详细说明:
-
访问1:缓存为空,将1加入缓存。
- 缓存: {1}
-
访问2:2不在缓存中,将2加入缓存。
- 缓存: {1, 2}
-
访问3:3不在缓存中,将3加入缓存。此时缓存满,根据LRU算法,最早加入的1将被替换掉。
- 缓存: {2, 3}
-
再次访问1:1不在缓存中,将1重新加入缓存。由于缓存已满,此时会替换掉最久未使用的2。
- 缓存: {3, 1}
-
访问4:4不在缓存中,将4加入缓存。此时会替换掉最久未使用的3。
- 缓存: {1, 4}
-
再次访问1:1已经在缓存中,并且是最近访问的,所以只需要将其移动到链表头部即可。
- 缓存: {4, 1}
最终,缓存中的数据顺序是 {4, 1},其中4是最久未被访问的数据,1是最近被访问的数据。
Python实现示例
以下是使用Python实现的一个简单的LRU缓存:
from collections import OrderedDictclass LRUCache:def __init__(self, capacity: int):self.cache = OrderedDict()self.capacity = capacitydef get(self, key: int) -> int:if key not in self.cache:return -1else:# Move the key to the end to show that it was recently usedself.cache.move_to_end(key)return self.cache[key]def put(self, key: int, value: int) -> None:if key in self.cache:# Update the value and move it to the endself.cache.move_to_end(key)else:if len(self.cache) == self.capacity:# Pop the first item as it's the least recently usedself.cache.popitem(last=False)# Insert the new key-value pairself.cache[key] = value# 使用LRU缓存
cache = LRUCache(2)
cache.put(1, 1) # 缓存是 {1=1}
cache.put(2, 2) # 缓存是 {2=2, 1=1}
print(cache.get(1)) # 返回 1, 缓存是 {2=2, 1=1}
cache.put(3, 3) # LRU 替换 2,缓存是 {3=3, 1=1}
在这个例子中,OrderedDict
维护了访问顺序,使得我们可以快速地移动最近访问的项到末尾,以及在必要时移除最早访问的项。