LRU, 內存管理的一種頁面置換算法,對於在內存中但又不用的數據塊(內存塊)叫作LRU,操做系統會根據哪些數據屬於LRU而將其移出內存而騰出空間來加載另外的數據python
緩存使用策略有三種算法
維護一個有序單鏈表. 尾部是最近使用的, 頭部是最先使用的. 當有一個新數據被訪問時, 遍歷該鏈表, 有如下狀況數組
若是直接使用單鏈表
實現的話, 查找操做時間複雜度是O(n), 因此一般還會再借助散列表
來提升查找速度. 可是在空間已滿的時候須要刪除最先使用的數據, 因此還須要保證使用順序緩存
實現有序的散列表: 藉助散列表和雙向鏈表實現, 散列表用來快速定位, 雙向鏈表用來存儲數據數據結構
# coding:utf-8 from collections import OrderedDict class LRUCache(object): """ 藉助OrderedDict的有序性實現, 內部使用了雙向鏈表 """ def __init__(self, max_length: int = 5): self.max_length = max_length self.o_dict = OrderedDict() def get(self, key): """ 若是找到的話移動到尾部 :param key: :return: """ value = self.o_dict.get(key) if value: self.o_dict.move_to_end(key) return value def put(self, key, value): if key in self.o_dict: self.o_dict.move_to_end(key) else: if len(self.o_dict) >= self.max_length: # 彈出最早插入的元素 self.o_dict.popitem(last=False) self.o_dict[key] = value if __name__ == "__main__": lru = LRUCache(max_length=3) lru.put(1, "a") lru.put(2, "b") lru.put(3, "c") assert lru.o_dict == OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')]) lru.get(2) assert lru.o_dict == OrderedDict([(1, 'a'), (3, 'c'), (2, 'b')]) lru.put(4, "d") assert lru.o_dict == OrderedDict([(3, 'c'), (2, 'b'), (4, "d")])
# coding:utf-8 from collections import deque class LRUCache(object): def __init__(self, max_length: int = 5): self.max_length = max_length self.cache = dict() self.keys = deque() def get(self, key): if key in self.cache: value = self.cache[key] self.keys.remove(key) self.keys.append(key) else: value = None return value def put(self, key, value): if key in self.cache: self.keys.remove(key) self.keys.append(key) else: if len(self.keys) >= self.max_length: self.keys.popleft() self.keys.append(key) else: self.keys.append(key) self.cache[key] = value if __name__ == "__main__": lru = LRUCache(max_length=3) lru.put(1, "a") lru.put(2, "b") lru.put(3, "c") assert lru.keys == deque([1, 2, 3]) lru.get(2) assert lru.keys == deque([1, 3, 2]) lru.put(4, "d") assert lru.keys == deque([3, 2, 4])
可使用python3.7中自帶的lru緩存模塊app
from functools import lru_cache @lru_cache(maxsize=32) def fibs(n: int): if n == 0: return 0 if n == 1: return 1 return fibs(n-1) + fibs(n-2) if __name__ == '__main__': print(fibs(10))