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))