LRU快取演算法

2021-08-02 21:29:07 字數 2602 閱讀 7862

為什麼要有lru快取演算法

我們用快取來存放以前讀取的資料,而不是直接丟掉,這樣,再次讀取的時候,可以直接在快取裡面取,而不用再重新查詢一遍,這樣系統的反應能力會有很大提高。但是,當我們讀取的個數特別大的時候,我們不可能把所有已經讀取的資料都放在快取裡,畢竟記憶體大小是一定的,我們一般把最近常讀取的放在快取裡。現在,我們就來研究這樣一種快取機制——lru快取。

lru快取:

lru快取利用了這樣的一種思想。lru是least recently used 的縮寫,翻譯過來就是「最近最少使用」,也就是說,lru快取把最近最少使用的資料移除,讓給最新讀取的資料。而往往最常讀取的,也是讀取次數最多的,所以,利用lru快取,我們能夠提高系統的效能.

lru快取策略實現原理

1、使用雙向鍊錶記錄資料的被使用的時間 

因為我們要刪除最久沒有被訪問的資料,為了保證效率,我們在快取中維護乙個雙向鍊錶,該鍊錶將快取中的資料按照訪問時間從新到舊排列起來。 

當我們需要訪問乙個資料的時候,如果快取中已經快取了這個資料,那麼我們就將該資料從快取的雙向鍊錶中摘除,然後再重新放入到雙向鍊錶的表頭。 

如果快取中沒有我們需要的資料,那麼我們可以在外部獲得資料,然後將資料放入到快取中,此過程中會將新資料插入到雙向鍊錶的表頭。

2、使用hash表保證快取中資料的訪問速度 

因為鍊錶進行查詢是o(n),比較慢。因此為了提高效率,我們除了將資料維護在乙個雙向鍊錶中,同時還將資料維護在乙個hash表中,這時我們訪問的效率就變成了o(1)。

lru快取策略的兩個方法

為最近最少使用(lru)快取策略設計乙個資料結構,它應該支援以下操作:獲取資料(get)和寫入資料(set)。

獲取資料get(key):如果快取中存在key,則獲取其資料值(通常是正數),否則返回-1。

寫入資料set(key, value):如果key還沒有在快取中,則寫入其資料值。當快取達到上限,它應該在寫入新資料之前刪除最近最少使用的資料用來騰出空閒位置。

原理**

下面是**分析,末尾都有注釋,很詳細

#define _crt_secure_no_warnings 1

#include "lrucache.h"

void test()

};templatestruct isequal

};template>

class lrucache

~lrucache()

public:

//向快取中放入資料

void lrucacheset(k key, t data)

} else //cur != null

}//從快取中得到資料

bool lrucacheget(k key, t& data)

else

}private:

//刪除雙向鍊錶

void _deletelist(node* head) }

void _updatelrulist(node* node)

//移除在hashmap中的指定節點

void _removefromhashmap(node* node)

}else//移除的節點是普通節點

}} }

//移除雙向鍊錶的指定節點(注意是移除不是刪除,因為hashmap中還有結點呢,如果乙個節點刪除兩次,那麼程式會崩潰)

void _removefromlist(node* node)

if (_lrulisthead == _lrulisttail)//只有乙個節點的情況下

else if (node == _lrulisthead)//刪除的節點是頭結點的情況

else if (node == _lrulisttail)//刪除的節點是尾結點的情況

else

--_size;

} //將快取節點插入鍊錶的頭部

node* _insertevaltolisthead(node* node)

if (null == _lrulisthead)//如果當前鍊錶中沒有節點

else//直接進行頭插

return lastnode;

} //將快取節點插入hashmap中

void _insertevaltohashmap(node* node)

else//cur != null

}int _hashfunc(const k& key)

//從hashmap中獲取乙個快取單元

node* _getvalfromhashmap(const k& key)

//拉鍊法

cur = cur->_hashlistnext;

}}

return null;

}private:

size_t _capacity;//快取的容量

node** _hashmap;//hash陣列

node* _lrulisthead;//指向雙向鍊錶的頭指標

node* _lrulisttail;//指向雙向鍊錶的尾指標

size_t _size;//記錄當前快取節點的個數

};

LRU演算法 快取演算法

lru演算法主要用於快取演算法,在節省資源的情況下提高資料訪問效率 篩選熱點資料 對不斷訪問的資料進行篩選淘汰,剩下的資料就為熱點資料 相對而言,釋放最近未被訪問資料占用的空間也是採用lru演算法。1 lru的實現 鍊錶 使用乙個鍊錶儲存快取資料 1 新資料插入到鍊錶頭部 2 每當快取命中 即快取資...

快取淘汰演算法 LRU

1.lru 1.1.原理 lru least recently used,最近最少使用 演算法根據資料的歷史訪問記錄來進行淘汰資料,其核心思想是 如果資料最近被訪問過,那麼將來被訪問的機率也更高 1.2.實現 最常見的實現是使用乙個鍊錶儲存快取資料,詳細演算法實現如下 1.新資料插入到鍊錶頭部 2....

LRU 快取淘汰演算法

1.介紹 lru是leastrecentlyused近期最少使用演算法。記憶體管理的一種頁面置換演算法,對於在記憶體中但又不用的資料塊 記憶體塊 叫做lru,oracle會根據哪些資料屬於lru而將其移出記憶體而騰出空間來載入另外的資料。lru least recently used,最近最少使用 ...