データ構造とアルゴリズム-LRU

LRU、メモリ管理ページ置換アルゴリズムの一種ではなく、データ・ブロック(メモリブロック)用のメモリでは、LRU、データはLRUに基づいて、追加のデータをロードするためにスペースを作るために、メモリの外に移動属するオペレーティングシステムと呼ばれています

3つのキャッシュ使用ポリシーがあります。

  • (先入れ先出し待ち行列で)FIFO
  • LFU -頻度の最も低い(最低使用)に使用し
    、最新の小さな数のデータの一部がアクセスされた場合は、将来的に数が非常に少ないアクセスすることが
  • LRU -最も最近(最低使用)に使用され
    、最近では、データの一部がアクセスされていない場合、確率はアクセスされた後、非常に小さいです

スキーム:O(N)

単一順序付けられたリストを維持する。テールが最近使用され、ヘッドが使用する最初のものである。リストを横断するときに、新しいデータにアクセスすると、次のような状況

  1. リストにキャッシュされている場合は、このノードを取得、削除の末尾に移動
  2. キャッシュされない場合
    • リストは、直接尾に、満杯でない場合
    • リストがいっぱいになった場合は、新しいノードの頭と尾を削除

直接使用する場合は单链表真、動作時間の複雑さはO(n)があるので、通常は別の手段があるだろう求める散列表検索速度を向上させる。しかし、スペースはデータの完全であるとき、最初の使用を除去する必要があるので、それが配列の使用ことを確認する必要があります

オプションII:O(1)

整然としたハッシュテーブル:双方向のハッシュテーブルとリンクリストの実装では、ハッシュテーブルを迅速に検索するために使用され、データを格納するために使用される二重リンクリスト

実現

使用OrderDict達成

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

lru_cache

あなたが運ぶpython3.7キャッシュモジュールLRUで使用することができます

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

アプリケーション

  • LRUポリシーのRedis
  • JavaののLinkedHashMap
    ハッシュテーブルを使用し、二重リンクリストを実装

概要

  • 配列はすぐに見つけるためにインデックスを使用しますが、欠点は、必要性、連続したメモリであります
  • チェーン利点は、メモリが連続することはできませんが、遅い見つけることということです
  • ハッシュ、リスト/ジャンプテーブルミックスは、配列とリンクリストの長所を組み合わせることです

データ

  • 米国のデータ構造とアルゴリズム - 紛争の王

おすすめ

転載: www.cnblogs.com/zlone/p/11012097.html