LRU (Least Recently Used) キャッシュアルゴリズムの実装

LRU (Least Recently Used) キャッシュアルゴリズムの実装

[[349478]]

LRU は Least Recently Used の略で、よく使われるページ置換アルゴリズムです。長い間使われていないページを削除します。実は、これも非常にシンプルで、人気のないページを適時に削除して、トイレを占領してリソースを無駄にしないようにするものです。

LRU は一般的なページ置換アルゴリズムです。コンピューティングでは、すべてのファイル操作をメモリ内で実行する必要があります。ただし、コンピュータのメモリのサイズは固定されているため、すべてのファイルをメモリにロードすることはできません。そのため、メモリに追加されるファイルを選択する戦略を開発する必要があります。

一般的なページ置換アルゴリズムは次のとおりです。

  • LRU 最近未使用
  • FIFO先入先出置換アルゴリズムはキューに似ている
  • OPT 最適順列アルゴリズム (理想)
  • NRU クロック置換アルゴリズム
  • LFU 最も使用頻度の低い置換アルゴリズム
  • PBA ページ バッファ アルゴリズム

LRU原則

LRU の設計原則は、データが最近の期間に頻繁にアクセスされた場合、将来も頻繁にアクセスされるというものです。つまり、頻繁にアクセスされるデータであれば、すぐにヒットするようにする必要があり、頻繁にアクセスされないデータであれば、容量が制限を超えたときに削除する必要があります。

コアはスタックを使用して操作を実行することであり、主にgetとputの2つの操作が含まれます。

得る

取得時に、スタック内に値がある場合は、その値のキーがスタックの先頭に移動され、ない場合は null が返されます。

置く

スタックがいっぱいでないとき、スタックに入れるキーがあれば、そのキーに対応する値を更新し、キーの値をスタックの一番上に持ってきます。入れるキーがない場合は、そのままスタックにプッシュします。

スタックがいっぱいになったとき、スタックに入れるキーがある場合は、このキーに対応する値を更新し、キーの値をスタックの一番上に置きます。スタックに入れるキーがない場合は、スタックの一番下の要素を削除し、値をスタックの一番上に置きます。

解決策:配列を維持し、get メソッドと put メソッドを提供し、最大数を制限します。

get を使用すると、要素を最近使用したものとしてマークし、最初の項目に昇格させることができます。 put はキー値を追加できますが、最大制限に達したかどうかを判断する必要があります。

達していない場合は、配列の最初の項目に直接挿入できます。 最大制限 max に達した場合は、データの末尾の要素を削除する必要があります。

  1. LRUCache cache = new LRUCache( 2 /* キャッシュ容量 */ );
  2.  
  3. キャッシュに1をセットします。
  4. キャッシュにデータを格納する。
  5. cache.get(1); // 1を返す
  6. cache.put(3, 3); // この操作によりキー2が無効になります
  7. cache.get(2); // -1 を返します (見つかりません)
  8. cache.put(4, 4); // この操作によりキー1が無効になります
  9. cache.get(1); // -1 を返します (見つかりません)
  10. cache.get(3); // 3 を返す
  11. cache.get(4); // 4を返す

LRUアルゴリズムの設計

上記の操作プロセスを分析すると、putメソッドとgetメソッドの時間計算量をO(1)にするために、キャッシュデータ構造に必要な条件として、高速検索、高速挿入、高速削除、および順序をまとめることができます。

明らかに、キャッシュは最近使用されたデータと長い間使用されていないデータを区別するためにソートされる必要があるため、キーがすでに存在するかどうかを確認するためにキャッシュを調べる必要があり、容量がいっぱいの場合は最後のデータを削除する必要があり、各アクセスではデータをキューの先頭に挿入する必要もあります。

では、上記の条件を同時に満たすデータ構造は何でしょうか? ハッシュ テーブルは検索が高速ですが、データには固定の順序がありません。リンク リストには順序があり、挿入と削除は高速ですが、検索は低速です。そこで、これらを組み合わせて、ハッシュ リンク リストという新しいデータ構造を形成します。

LRU キャッシュ アルゴリズムのコア データ構造は、二重リンク リストとハッシュ テーブルを組み合わせたハッシュ リストです。このデータ構造は次のようになります。

js実装

  • 特定のコードの一般的な解決策は、配列項目にキーと値のペアのオブジェクトを格納する配列を維持することです。毎回、キー値が配置されている配列インデックス操作を見つけるためにトラバースする必要があります。

leetCode 146 テストに合格しました。実行時間: 720 ミリ秒。メモリ使用量: 58.5 MB。

  1. 関数LRUCache(容量) {
  2. this.capacity = capacity; // 最大制限
  3. this.cache = [];
  4. };
  5.  
  6. /**
  7. * @param {数値}キー 
  8. * @return {数値}
  9. */
  10. LRUCache.prototype.get =関数(キー) {
  11. index = this.cache.findIndex((item) => item.key === key )とします。
  12. if (インデックス=== -1 ) {
  13. -1 を返します
  14. }
  15. // この要素を削除し、配列の最初の項目に挿入します
  16. 値を this.cache[インデックス].value とします。
  17. this.cache.splice(インデックス, 1);
  18. this.cache.unshift({
  19. 価値、
  20. });
  21. 戻り値;
  22. };
  23.  
  24. /**
  25. * @param {数値}キー 
  26. * @param {数値} 値
  27. * @return {void}
  28. */
  29. LRUCache.prototype.put =関数(キー、値) {
  30. index = this.cache.findIndex((item) => item.key === key )とします。
  31. // 挿入したいデータは既に存在するので、それを昇格するだけです
  32. if (インデックス> -1 ) {
  33. this.cache.splice(インデックス, 1);
  34. }そうでない場合 (this.cache.length >= this.capacity) {
  35. // 最大制限に達した場合は、最初に最も長い間使用されていないものを削除します
  36. this.cache.pop();
  37. }
  38. this.cache.unshift({キー、値 });
  39. };

実際には、上記のアプローチにはバリエーションがあります。オブジェクトを使用してキーと値のペアを保存し、配列を使用してキーの順序を保存できます。

  • 高度な要件 O(1)

時間の計算量は O(1) なので、配列を走査してキー値を見つけることはできません。 ES6 の Map を使用するとこの問題を解決できます。Map はキーと値のペアを維持できるだけでなく、挿入順序も記憶できるためです。

  1. 関数LRUCache(容量) {
  2. this.cache = 新しい Map();
  3. this.capacity = capacity; // 最大制限
  4. };
  5.  
  6. LRUCache.prototype.get =関数(キー) {
  7. if (this.cache.has(キー)) {
  8. // 存在する場合は更新する
  9. temp = this.cache.get(キー) とします。
  10. this.cache.delete (キー) ;
  11. this.cache.set (キー temp ) ;
  12. 戻る 温度;
  13. }
  14. -1 を返します
  15. };
  16.  
  17. LRUCache.prototype.put =関数(キー、値) {
  18. if (this.cache.has(キー)) {
  19. // 存在する場合は更新します(削除してから追加します)
  20. this.cache.delete (キー) ;
  21. }そうでない場合 (this.cache.size > = this.capacity) {
  22. // 存在しない場合は追加します
  23. // キャッシュが最大値を超えた場合は、最近使用されていないものを削除します
  24. this.cache.delete (this.cache.keys(). next ().value);
  25. }
  26. this.cache.set (キー、値 );
  27. };

<<:  自動運転技術が盛んに進歩していますが、実際に道路上で実用化されるまでにはどれくらい時間がかかるのでしょうか?

>>:  ニューラルネットワークの内部はどのようになっているのでしょうか?

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

各国の人工知能戦略の解釈

現在、人工知能の開発は引き続き盛んに行われており、新世代の科学技術革命の先駆者となりつつあります。米...

2021 年のトップ 12 AI ツールとフレームワーク

AI トレンドがあらゆるところで広がる 2021 年を迎える準備はできていますか? ここでは、202...

XML暗号化アルゴリズムが破られ、W3CはXML暗号化標準を改訂する必要がある

ルール研究所の研究者らは、XML 暗号化プロトコルに重大なセキュリティ上の脆弱性を発見し、シカゴで開...

...

未来はAIエンジニアの手に。しかし変革を成功させるのは簡単ではない

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

インテリジェントコンピューティングセンター構築の「サンゴ礁」と「灯台」

インテリジェント コンピューティング センターを「誰でもアクセス可能かつ無料」にする時が来ています。...

Microsoft Bing Chat が Chrome と Safari で利用可能になりましたが、いくつかの制限があります

Microsoft の人工知能チャットボット Bing Chat が、Google Chrome お...

金融業界における AI とビッグデータのトップ 10 トレンド

今日では、人々の仕事や生活のあらゆる側面がテクノロジーによって支援されています。人工知能はそのような...

AI時代に誰かが密かにあなたの顔を真似している

人工知能の時代音声、指紋、顔認識など。 AI技術は飛躍的に進歩している犯罪者もこれに気づいているこの...

ディープラーニングとディープクローニング: チャットボットにとってより優れたソリューションはどちらでしょうか?

[[200112]]編集者注: チャットボットは目新しいものではありません。Facebook や ...

...

ああはは、それだ!人気の機械学習アルゴリズムの 4 つの「なるほど!」という瞬間

ほとんどの人は 2 つのグループに分かれます。これらの機械学習アルゴリズムが理解できません。アルゴリ...

Facebookは色を表現するために通信する2つのニューラルネットワークを作成

色をどのように表現するか考えたことはありますか?最新の研究によると、人間は個別の記号を使用して領域の...