python LRUキャッシュの淘汰を実現
4890 ワード
LRU Least Recent usedは最近最も少なくアルゴリズムを使用して、主にキャッシュ淘汰に用いる.主な目的は、最近最も使用されているデータをメモリから削除し、他のデータをロードすることです.
原理: 新しいデータがある場合(データが以前にキャッシュされていないことを意味する)、リストヘッダキャッシュに加入して最大容量に達した場合、データの多いデータを淘汰する必要がある.この場合、淘汰リストの末尾のデータはキャッシュ中にデータがヒットした場合、データをリストヘッダに移動する(新たにキャッシュに加入することに相当する)
前述の文章から分かるように、キャッシュを簡略化すると2つの機能があり、1つはデータ(キャッシュデータ)を内蔵し、1つはデータ(ヒットキャッシュ)を外部に吐き出すので、私たちのキャッシュは外部にputとgetの2つのインタフェースだけでよい.
キャッシュ内部ではLRUロジックを1つのリスト(list)だけで実現できますが、リストではロジックが実現できますが、キャッシュにヒットしたかどうかを判断する際には、速度が非常に遅い可能性があります(リストはデータが入っているかどうかを知るために遍歴する必要があります).Pythonでは,辞書(dict)や集合(set)のようなhashベースの構造を用いて,データが存在するか否かを迅速に判断し,リスト実装の性能問題を解決することができる.しかし、辞書(python 3.6以降の順序)と集合には順序がなく、並べ替え可能でhashベースのデータ構造があればよい.
Pythonのcollectionsパッケージには、このような実用的な構造OrderedDictが内蔵されており、OrderedDictはdictのサブクラスであるが、内部に格納されている要素は秩序化されている(リストの特徴).
原理: 新しいデータがある場合(データが以前にキャッシュされていないことを意味する)、リストヘッダキャッシュに加入して最大容量に達した場合、データの多いデータを淘汰する必要がある.この場合、淘汰リストの末尾のデータはキャッシュ中にデータがヒットした場合、データをリストヘッダに移動する(新たにキャッシュに加入することに相当する)
前述の文章から分かるように、キャッシュを簡略化すると2つの機能があり、1つはデータ(キャッシュデータ)を内蔵し、1つはデータ(ヒットキャッシュ)を外部に吐き出すので、私たちのキャッシュは外部にputとgetの2つのインタフェースだけでよい.
キャッシュ内部ではLRUロジックを1つのリスト(list)だけで実現できますが、リストではロジックが実現できますが、キャッシュにヒットしたかどうかを判断する際には、速度が非常に遅い可能性があります(リストはデータが入っているかどうかを知るために遍歴する必要があります).Pythonでは,辞書(dict)や集合(set)のようなhashベースの構造を用いて,データが存在するか否かを迅速に判断し,リスト実装の性能問題を解決することができる.しかし、辞書(python 3.6以降の順序)と集合には順序がなく、並べ替え可能でhashベースのデータ構造があればよい.
Pythonのcollectionsパッケージには、このような実用的な構造OrderedDictが内蔵されており、OrderedDictはdictのサブクラスであるが、内部に格納されている要素は秩序化されている(リストの特徴).
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.queue = OrderedDict()
def get(self, key):
# -1
if key not in self.queue:
return -1
#
value = self.queue.pop(key)
#
#
self.queue[key] = value
return self.queue[key]
def put(self, key, value):
# ,
if key in self.queue:
self.queue.pop(key)
# ,
elif len(self.queue.items()) == self.capacity:
#
self.queue.popitem(last=False)
#
self.queue[key] = value