LRUキャッシュアルゴリズムのメモ

 

LRU原理と分析

   LRUは、最低使用頭文字であること、最も最近のデータを使用LRUキャッシュは、最新のデータが読み与える、削除され、「最低使用」に変換されます。ほとんどの場合、そのLRUキャッシュを使用し、また、最も多くを読んで、読んで、私たちは、システムのパフォーマンスを向上させることができます。

LRUは達成します

   LRU

   1.新しいデータがリンクリストの先頭に挿入されています。

   2.たびにキャッシュヒット(すなわち、キャッシュデータをアクセスする)、データがリンクリストの先頭に移動されます。

   リストがいっぱいになると3、リンクリストデータの尾は破棄されます。

LRU分析

   [ヒット]

   ホットデータ、LRUの良い効率が、散発的がある場合は、定期的なバッチ操作は、LRUの急激な減少につながるヒット率、キャッシュ汚染は非常に深刻です。

   [複雑]

   シンプル。

   [費用]

   データ・ブロック・インデックス・ヒットを見つけるために、リストを横断に必要なヒットは、その後、頭部にデータを移動する必要があります。

 

LRUは達成します

ディテール

添加元素时,放到链表头
缓存命中,将元素移动到链表头
缓存满了之后,将链表尾的元素删除

LRUアルゴリズム

  • 二重にリンクされたリストには、データを保存するために使用することができます
  • 使用ハッシュO(1)アクセスを実現

LRUアルゴリズム(ゴー言語)groupcache
https://github.com/golang/groupcache/blob/master/lru/lru.goを

出典シンプルコメント:

パッケージLRU

輸入「コンテナ/リスト」

//キャッシュの構造、定義されたLRUキャッシュはスレッドセーフではありません
タイプのキャッシュ構造体{
    //上限数、0は無制限です 
    MaxEntries int型

    削除//ときは、オプションのコールバック関数を追加することができます
    OnEvicted FUNC(キーキー、値インタフェース{})

    リンクリストを使用してセーブデータLL * list.List //
    キャッシュ地図【インターフェース{}] * list.Element //マップ 
}

//キーは、比較される任意の値であるhttp://golang.org/ref/spec#Comparison_operators
} {キーインターフェイスを入力

タイプ・エントリ構造体{
    キーキー
    値インターフェース{}
}

//新しいキャッシュオブジェクトを作成します。
FUNC新(maxEntries int型)*キャッシュ{
    リターン&キャッシュ{
        MaxEntries:maxEntries、
        LL:list.New()、
        キャッシュ:メイク(マップ[インターフェイス{}] * list.Element)
    }
}

//キャッシュ内に新しい値を追加
FUNC追加(*キャッシュC)(キーキー、値インタフェース{}){
    もしc.cache ==ゼロ{
        c.cache =メイク(マップ[インターフェイス{}] * list.Element)
        c.ll = list.New()
    }
    = c.cache [キー];:EE、OKであれば OK {
                //キャッシュヒットは、リストの先頭に移動します
        c.ll.MoveToFront(EE)
        ee.Value。(*エントリー).VALUE =値
        リターン
    }
        //リストの先頭にデータを追加
    ELE:= c.ll.PushFront(&エントリ{キー、値})
    c.cache [キー]はそれを=
    もしc.MaxEntries!= 0 && c.ll.Len()> c.MaxEntries {
        //要素への最後のフルアクセスを削除します
        c.RemoveOldest()
    }
}

//代わりに、キャッシュから値を取得します。
FUNC(C *キャッシュ)を取得します(キーキー)(値インタフェース{}、[OK]をブール値){
    もしc.cache ==ゼロ{
        リターン
    }
    ELE場合、ヒット:= c.cache [キー]。ヒット{
        //キャッシュヒット、ヒットの要素は、リストの先頭に移動します
        c.ll.MoveToFront(ELE)
        ele.Valueを返します。(*エントリー).VALUE、真
    }
    リターン
}

//指定されたキー要素を削除
FUNC(C *キャッシュ)を削除(キーキー){
    もしc.cache ==ゼロ{
        リターン
    }
    ELE場合、ヒット:= c.cache [キー]。ヒット{
        c.removeElement(ELE)
    }
}

//最後の訪問の要素を削除します
FUNC(C *キャッシュ)RemoveOldest(){
    もしc.cache ==ゼロ{
        リターン
    }
    ELE:= c.ll.Back()
    もしELE!= nilの{
        c.removeElement(ELE)
    }
}

FUNC(C *キャッシュ)removeElement(E * list.Element){
    c.ll.Remove(E)
    KV:= e.Value(*エントリー)。
    削除(c.cache、kv.key)
    もしc.OnEvicted!= nilの{
        c.OnEvicted(kv.key、kv.value)
    }
}

//キャッシュバッファ数
FUNCレン(){int型(*キャッシュC)
    もしc.cache ==ゼロ{
        0を返します
    }
    リターンc.ll.Len()
}

  

LRU-K

   Kは、最も最近使用されたLRU-Kの数を表し、したがってLRU LRU-1とみなすことができます。LRU-Kの主な目的は、問題「キャッシュ汚染」LRUアルゴリズムを解決することであり、核となるアイデアは、のために「最近使用した1時間」の基準を拡張することで、「最近使用したK回。」

実現

   LRUを比較すると、より多くの履歴ビーイングのためのキューを維持するために、LRU-Kの必要性は、すべてのキャッシュされたデータを記録してアクセス。アクセスデータの数は、キャッシュにデータの前にK回に達した場合のみ。データを排除するときに必要な、LRU-Kは、現在の時刻から最大のデータをK番目のアクセス時間を排除するであろう。詳細は、以下を実現します:

   LRU-K

   1.データは、最初のアクセス履歴リストに追加、アクセスされます。

   2.履歴リスト内のデータへのアクセスは、その後除去特定のルール(FIFO、LRU)に従ってK訪問し、達していない場合。

   3.データ・アクセス履歴キューへのアクセス回数がK回に達したときに、インデックスデータは、時間によって再注文したキャッシュに履歴キュー、キューデータから削除され、このデータをキャッシュし、キャッシュキューされます。

   4.データバッファキューを並べ替え、再度アクセスされた後。

   キュー行バッファのデータを排除する5.必要性、すなわち、データの最後に、段階的に廃止:データ消去「今、最も古いから最後から二番目のK訪問を」。

   LRU LRU-Kは、LRUの欠点を回避できる一方、LRU-2の実用的なアプリケーションは、様々な要因のために最良の選択である、という利点を有する、LRU-3以上は、K値が高いヒット率が、貧しい適応となり、これは、過去のデータへのアクセス記録へのアクセスの多くはクリアが必要です。

分析

   [ヒット]

   LRU-Kは、ヒット率がLRUより高いによって引き起こされる「キャッシュ汚染」の問題を低減します。

   [複雑]

   LRU-K・キューは、優先キュー、アルゴリズムの複雑さとコストが比較的高いです。

   [費用]

   LRU-Kはまた、それらのオブジェクトを記録する必要があるため、アクセスが、メモリの消費量がよりLRU以上になるよう、キャッシュ内に配置されていない、場合に大量のデータ、メモリ消費量がより印象的であろう。

   ソートするのに必要な時間に基づいて、LRU-Kは、(並べ替えたときに段階的に廃止することができ、それが瞬時に並べ替えることができます)、CPUの消費量は、LRUよりも高くなっています。

 

 

おすすめ

転載: www.cnblogs.com/-wenli/p/12090871.html