LRU 和 LFU 缓存实施有什么区别?
我知道可以使用LinkedHashMap
实现LRU。
但是如何实现LFU缓存?
答案 0 :(得分:50)
让我们考虑一个缓存容量为3的恒定缓存请求流,见下文:
A, B, C, A, A, A, A, A, A, A, A, A, A, A, B, C, D
如果我们只考虑一个带有O(1)驱逐时间和O(1)加载时间的HashMap +双向链表实现的最近最少使用(LRU)缓存,我们将得到以下内容处理缓存请求时缓存的元素如上所述。
[A]
[A, B]
[A, B, C]
[B, C, A] <- a stream of As keeps A at the head of the list.
[C, A, B]
[A, B, C]
[B, C, D] <- here, we evict A, we can do better!
当你看这个例子时,你可以很容易地看到我们可以做得更好 - 鉴于将来要求A的预期机会更高,即使它是最近最少使用的,我们也不应该逐出它。
A - 12
B - 2
C - 2
D - 1
最不常用(LFU)缓存通过跟踪缓存请求在其逐出算法中使用了多少次来利用此信息。
答案 1 :(得分:11)
LRU是一种称为最近最少使用的缓存的缓存逐出算法。
看看这个resource
LFU是一种称为最不常用的缓存的缓存逐出算法。
它需要三个数据结构。一个是哈希表,用于缓存键/值,以便给定一个键,我们可以在O(1)处检索缓存条目。第二个是每个访问频率的双链表。最大频率限制在高速缓存大小,以避免创建越来越多的频率列表条目。如果我们有一个最大大小为4的缓存,那么我们将得到4个不同的频率。每个频率将具有双链表以跟踪属于该特定频率的高速缓存条目。 第三种数据结构将以某种方式链接这些频率列表。它可以是一个数组或另一个链表,这样在访问高速缓存条目时,它可以很容易地在时间O(1)中提升到下一个频率列表。
答案 2 :(得分:3)
主要区别在于,在LRU中,我们只检查最近使用旧页面的页面比其他页面更新,即仅根据最近使用的页面进行检查。 但是在LFU我们检查旧页面以及该页面的频率,如果页面的频率比旧页面大,我们不能删除它,如果我们所有的旧页面具有相同的频率,那么采取最后一个即FIFO方法。并删除页面....