LRU Cache的原理和python的實現

mug發表於2021-09-09

LRU Cache的原理和python的實現

LRU的原理

LRU(Least Recently Used)即最近最少使用。 作業系統中一種記憶體管理的頁面置換演算法,主要用於找出記憶體中較久時間沒有使用的記憶體塊,將其移出記憶體從而為新資料提供空間。此演算法的前提是認為:當一個資料被訪問的越頻繁,則這個資料在未來被訪問的機率就越高。

LRU演算法其實就是按照使用順序將元素倒敘排列,在有限的儲存空間中,若空間滿時,刪除最後的元素(即最久沒有使用的元素)。若想實現高效實現這個演算法,使get和set都能O(1)的效率,需要一個有序的字典。

LRU的Python實現(庫函式版)

首先實現一個雙向連結串列, 沒啥好說的,簡單實現一下:
class Node:

    def __init__(self, data, _pre=None, _next=None):        self.data = data        self._pre = _pre        self._next = _next    def __str__(self):        return str(self.data)class DoublyLink:

    def __init__(self):        self.tail = None        self.head = None        self.size = 0

    def insert(self, data):        if isinstance(data, Node):

            tmp_node = data        else:

            tmp_node = Node(data)        if self.size == 0:            self.tail = tmp_node            self.head = self.tail        else:

            self.head._pre = tmp_node

            tmp_node._next = self.head            self.head = tmp_node        self.size += 1

        return tmp_node    def remove(self, node):        if node == self.head:

            self.head._next._pre = None            self.head = self.head._next

        elif node == self.tail:

            self.tail._pre._next = None            self.tail = self.tail._pre        else:

            node._pre._next = node._next

            node._next._pre = node._pre        self.size -= 1

    def __str__(self):

        str_text = ""

        cur_node = self.head        while cur_node != None:

            str_text += cur_node.data + " "

            cur_node = cur_node._next        return str_text
實現LRU演算法
  • 插入資料時:若空間滿了,則刪除連結串列尾部元素,在進行插入

  • 查詢資料時:先把資料刪除,再重新插入資料,保證了元素的順序是按照訪問順序排列

class LRUCache:

    def __init__(self, size):        self.size = size        self.hash_map = dict()        self.link = DoublyLink()    def set(self, key, value):        if self.size == self.link.size:

            self.link.remove(self.link.tail)        if key in self.hash_map:

            self.link.remove(self.hash_map.get(key))

        tmp_node = self.link.insert(value)        self.hash_map.__setitem__(key, tmp_node)    def get(self, key):

        tmp_node = self.hash_map.get(key)        self.link.remove(tmp_node)        self.link.insert(tmp_node)        return tmp_node.data
測試程式碼
r = LRUCache(3)

r.set("1", "1")

r.set("2", "2")

r.set("3", "3")

print r.link

r.get("1")

print r.link

r.set("4", "4")

print r.link>> 3 2 1>> 1 3 2>> 4 1 3

LRU的Python實現(OrderedDict)

OrderedDict的本質就是一個有序的dict,其實現也是透過一個dict+雙向連結串列
from collections import OrderedDictclass LRUCache:

    def __init__(self, size):        self.size = size        self.linked_map = OrderedDict()    def set(self, key, value):        if key in self.linked_map:

            self.linked_map.pop(key)        if self.size == len(self.linked_map):            self.linked_map.popitem(last=False)        self.linked_map.update({key: value})    def get(self, key):

        value = self.linked_map.get(key)        self.linked_map.pop(key)        self.linked_map.update({key: value})        return value
測試程式碼
r = LRUCache(3)

r.set("1", "1")

r.set("2", "2")

r.set("3", "3")

print r.linked_map

r.get("1")

print r.linked_map

r.set("4", "4")

print r.linked_map>> OrderedDict([('1', '1'), ('2', '2'), ('3', '3')])>> OrderedDict([('2', '2'), ('3', '3'), ('1', '1')])>> OrderedDict([('3', '3'), ('1', '1'), ('4', '4')])



作者:NeilShao
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/506/viewspace-2818817/,如需轉載,請註明出處,否則將追究法律責任。

相關文章