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. };

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

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

ブログ    

推薦する

2022年秋の採用戦争:アルゴリズム職は混み合い、Java開発も後退を余儀なくされる

[[411043]]コンピュータサイエンスの卒業生にとって、アルゴリズム関連の職は基本的に「高給」と...

...

マスク氏は人気検索に頻繁に登場、テスラは「過大評価されている」

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

チャット記録をアップロードして自分自身を「複製」する。このスタートアップは「ブラックミラー」の第 1 話を現実のものにしました

10年前に放映されたアメリカのテレビシリーズ「ブラックミラー」の第1話のタイトルは「Be Right...

...

AIは古い建物のエネルギー効率を変えるでしょうか?

スマート ビルディングの観点から見ると、AI は多くの居住者向けテクノロジーに統合され、建物やキャン...

ディープラーニング: シンプルだが限界のあるソリューション

ディープラーニング:幾何学的視点ディープラーニングに関する最も驚くべき事実は、それがいかにシンプルで...

2024年に誰もが備えるべき5つのテクノロジートレンド

機械知能、現実と仮想の境界線の曖昧化、そしてインターネットの継続的な進化は、私たちの生活に根本的な影...

...

自動運転車は未来の社会で老後の暮らしをどう変えるのか?

フロリダ州中部にある、約12万5000人の住民を抱えるザ・ビレッジの退職者コミュニティには、約750...

AI「コスプレ」の鍵はキャラクター設定にあり!復旦大学、人民大学などがビッグファイブ性格特性+MBTIテストを発表:特性回復率は82.8%に達し、OOCを否定

好きなアニメ小説のキャラクターとチャットしてみませんか?バーチャルコンパニオンが欲しいですか?あなた...

...

この病院のAI看護師は、人間の看護師の作業負荷を30%削減するためにオンライン化されました

[[270607]]看護師は医療現場を問わず需要が高いです。米国労働統計局の報告によると、看護師の求...

説明可能なAIと説明可能な機械学習:ブラックボックスに光を当てる

人工知能(AI)や機械学習の分野では、「ブラックボックス」という概念が常に大きな注目を集めています。...

Googleの華博士がICCV2021で新モデルを発表、卵を泡立てるだけでパンケーキを作りたいかどうかがわかる

機械学習モデルが現実世界でますます使用され、導入されるようになると、AI の意思決定は人々の日常生活...