LRU和LFU的區別

2021-08-26 18:12:27 字數 1808 閱讀 2286

對於web開發而言,快取必不可少,也是提高效能最常用的方式。無論是瀏覽器快取(如果是chrome瀏覽器,可以通過chrome:://cache檢視),還是服務端的快取(通過memcached或者redis等記憶體資料庫)。快取不僅可以加速使用者的訪問,同時也可以降低伺服器的負載和壓力。那麼,了解常見的快取淘汰演算法的策略和原理就顯得特別重要。

像瀏覽器的快取策略、memcached的快取策略都是使用lru這個演算法,lru演算法會將近期最不會訪問的資料淘汰掉。lru如此流行的原因是實現比較簡單,而且對於實際問題也很實用,良好的執行時效能,命中率較高。下面談談如何實現lru快取:

lru cache具備的操作:

lru實現採用雙向鍊錶 + map 來進行實現。這裡採用雙向鍊錶的原因是:如果採用普通的單鏈表,則刪除節點的時候需要從表頭開始遍歷查詢,效率為o(n),採用雙向鍊錶可以直接改變節點的前驅的指標指向進行刪除達到o(1)的效率。使用map來儲存節點的key、value值便於能在o(logn)的時間查詢元素,對應get操作。

雙鏈表節點的定義:

struct cachenode 

};

對於lrucache這個類而言,建構函式需要指定容量大小

lrucache(int capacity)

雙鏈表的節點刪除操作:

void remove(cachenode *node)

else

if (node -> next != null)

else

}

將節點插入到頭部的操作:

void sethead(cachenode *node)

head = node;

if (tail == null)

}

get(key)操作的實現比較簡單,直接通過判斷map是否含有key值即可,如果查詢到key,則返回對應的value,否則返回-1;

int get(int key)

else

}

set(key, value)操作需要分情況判斷。如果當前的key值對應的節點已經存在,則將這個節點取出來,並且刪除節點所處的原有的位置,並在頭部插入該節點;如果節點不存在節點中,這個時候需要在鍊錶的頭部插入新節點,插入新節點可能導致容量溢位,如果出現溢位的情況,則需要刪除鍊錶尾部的節點。

void set(int key, int value)

else

sethead(newnode);

mp[key] = newnode;

}}

至此,lru演算法的實現操作就完成了,完整的原始碼參考:

補充:lru和lfu的區別:

lru是最近最少使用頁面置換演算法(least recently used),也就是首先淘汰最長時間未被使用的頁面!

lfu是最近最不常用頁面置換演算法(least frequently used),也就是淘汰一定時期內被訪問次數最少的頁!

比如,第二種方法的時期t為10分鐘,如果每分鐘進行一次調頁,主存塊為3,若所需頁面走向為2 1 2 1 2 3 4

注意,當調頁面4時會發生缺頁中斷

若按lru演算法,應換頁面1(1頁面最久未被使用) 但按lfu演算法應換頁面3(十分鐘內,頁面3只使用了一次)

可見lru關鍵是看頁面最後一次被使用到發生排程的時間長短,

而lfu關鍵是看一定時間段內頁面被使用的頻率!

LRU和LFU的區別

lru和lfu是不同的 lru是最近最少使用頁面置換演算法 least recently used 也就是首先淘汰最長時間未被使用的頁面 lfu是最近最不常用頁面置換演算法 least frequently used 也就是淘汰一定時期內被訪問次數最少的頁 比如,第二種方法的時期t為10分鐘,如果每...

LRU和LFU的區別

lru和lfu是不同的 lru是最近最少使用頁面置換演算法 least recently used 也就是首先淘汰最長時間未被使用的頁面 lfu是最近最不常用頁面置換演算法 least frequently used 也就是淘汰一定時期內被訪問次數最少的頁 比如,第二種方法的時期t為10分鐘,如果每...

LRU和LFU的區別

lru和lfu是不同的 lru是最近最少使用頁面置換演算法 least recently used 也就是首先淘汰最長時間未被使用的頁面 lfu是最近最不常用頁面置換演算法 least frequently used 也就是淘汰一定時期內被訪問次數最少的頁 比如,第二種方法的時期t為10分鐘,如果每...