沒有人能說清哪種緩衝演算法優於其他的緩衝演算法。(以下的幾種緩衝演算法,有的我也理解不好,如果感興趣,你可以Google一下)
Least Frequently Used(LFU):
大家好,我是 LFU,我會計算為每個緩衝對象計算他們被使用的頻率。我會把最不常用的緩衝對象踢走。
Least Recently User(LRU):
我是LRU緩衝演算法,我把最近最少使用的緩衝對象給踢走。
我總是需要去瞭解在什麼時候,用了哪個緩衝對象。如果有人想要瞭解我為什麼總能把最近最少使用的對象踢掉,是非常困難的。
瀏覽器就是使用了我(LRU)作為緩衝演算法。新的對象會被放在緩衝的頂部,當緩衝達到了容量極限,我會把底部的對象踢走,而技巧就是:我會把最新被訪問的緩衝對象,放到緩衝池的頂部。
所以,經常被讀取的緩衝對象就會一直呆在緩衝池中。有兩種方法可以實現我,array 或者是 linked list。
我的速度很快,我也可以被資料訪問模式適配。我有一個大家庭,他們都可以完善我,甚至做的比我更好(我確實有時會嫉妒,但是沒關係)。我家庭的一些成員包括LRU2 和 2Q,他們就是為了完善 LRU 而存在的。
Least Recently Used 2(LRU2):
我是 Least Recently Used 2,有人叫我最近最少使用twice,我更喜歡這個叫法。我會把被兩次訪問過的對象放入緩衝池,當緩衝池滿了之後,我會把有兩次最少使用的緩衝對象踢走。 因為需要跟蹤對象2次,訪問負載就會隨著緩衝池的增加而增加。如果把我用在大容量的緩衝池中,就會有問題。另外,我還需要跟蹤那麼不在緩衝的對象,因為他 們還沒有被第二次讀取。我比LRU好,而且是 adoptive to access 模式 。
Two Queues(2Q):
我是 Two Queues;我把被訪問的資料放到LRU的緩衝中,如果這個對象再一次被訪問,我就把他轉移到第二個、更大的LRU緩衝。
我踢走緩衝對象是為了保持第一個緩衝池是第二個緩衝池的1/3。當緩衝的訪問負載是固定的時候,把 LRU 換成 LRU2,就比增加緩衝的容量更好。這種機制使得我比 LRU2 更好,我也是 LRU 家族中的一員,而且是 adoptive to access 模式 。
Adaptive Replacement Cache(ARC):
我是 ARC,有人說我是介於 LRU 和 LFU 之間,為了提高效果,我是由2個 LRU 組成,第一個,也就是 L1,包含的條目是最近只被使用過一次的,而第二個 LRU,也就是 L2,包含的是最近被使用過兩次的條目。因此, L1 放的是新的對象,而 L2 放的是常用的對象。所以,別人才會認為我是介於 LRU 和 LFU 之間的,不過沒關係,我不介意。
我被認為是效能最好的緩衝演算法之一,能夠自調,並且是低負載的。我也儲存著曆史對象,這樣,我就可以記住那些被移除的對象,同時,也讓我可以看到被移除的對象是否可以留下,取而代之的是踢走別的對象。我的記憶力很差,但是我很快,適用性也強。
Most Recently Used(MRU):
我是 MRU,和 LRU 是對應的。我會移除最近最多被使用的對象,你一定會問我為什麼。好吧,讓我告訴你,當一次訪問過來的時候,有些事情是無法預測的,並且在緩衝系統中找出最少最近使用的對象是一項時間複雜度非常高的運算,這就是為什麼我是最好的選擇。
我是資料庫記憶體緩衝中是多麼的常見!每當一次緩衝記錄的使用,我會把它放到棧的頂端。當棧滿了的時候,你猜怎麼著?我會把棧頂的對象給換成新進來的對象!
First in First out(FIFO):
我是先進先出,我是一個低負載的演算法,並且對緩衝對象的管理要求不高。我通過一個隊列去跟蹤所有的緩衝對象,最近最常用的緩衝對象放在後面,而更早的緩衝對象放在前面,當緩衝容量滿時,排在前面的緩衝對象會被踢走,然後把新的緩衝對象加進去。我很快,但是我並不適用。
Second Chance:
大家好,我是 second chance,我是通過FIFO修改而來的,被大家叫做 second chance 緩衝演算法,我比 FIFO 好的地方是我改善了 FIFO 的成本。我是 FIFO 一樣也是在觀察隊列的前端,但是很FIFO的立刻踢出不同,我會檢查即將要被踢出的對象有沒有之前被使用過的標誌(1一個bit表示),沒有沒有被使用 過,我就把他踢出;否則,我會把這個標誌位清除,然後把這個緩衝對象當做新增緩衝對象排入佇列。你可以想象就這就像一個環隊列。當我再一次在隊頭碰到這個 對象時,由於他已經沒有這個標誌位了,所以我立刻就把他踢開了。我在速度上比FIFO快。
CLock
我是Clock,一個更好的FIFO,也比 second chance更好。因為我不會像second chance那樣把有標誌的緩衝對象放到隊列的尾部,但是也可以達到second chance的效果。
我持有一個裝有緩衝對象的環形列表,頭指標指向列表中最老的緩衝對象。當緩衝miss發生並且沒有新的緩衝空間時,我會問問指標指向的緩衝對象的標 志位去決定我應該怎麼做。如果標誌是0,我會直接用新的緩衝對象替代這個緩衝對象;如果標誌位是1,我會把頭指標遞增,然後重複這個過程,知道新的緩衝對 象能夠被放入。我比second chance更快。
Simple time-based:
我是 simple time-based 緩衝演算法,我通過絕對的時間周期去失效那些緩衝對象。對於新增的對象,我會儲存特定的時間。我很快,但是我並不適用。
Extended time-based expiration:
我是 extended time-based expiration 緩衝演算法,我是通過相對時間去失效緩衝對象的;對於新增的緩衝對象,我會儲存特定的時間,比如是每5分鐘,每天的12點。
Sliding time-based expiration:
我是 sliding time-based expiration,與前面不同的是,被我管理的緩衝對象的生命起點是在這個緩衝的最後被訪問時間算起的。我很快,但是我也不太適用。
好了!聽了那麼多緩衝演算法的自我介紹,其他的緩衝演算法還考慮到了下面幾點:
- 成本。如果緩衝對象有不同的成本,應該把那些難以獲得的對象儲存下來。
- 容量。如果緩衝對象有不同的大小,應該把那些大的緩衝對象清除,這樣就可以讓更多的小緩衝對象進來了。
- 時間。一些緩衝還儲存著緩衝的到期時間。電腦會失效他們,因為他們已經到期了。
根據緩衝對象的大小而不管其他的緩衝演算法可能是有必要的。
原文:http://www.zavakid.com/27
本文是使用 B3log Solo 從 簡約設計の藝術 進行同步發布的原文地址:http://88250.b3log.org/general-cache-algorithms.html