LRU緩存算法與pylru


這篇寫的略為糾結,算法原理、庫都是現成的,我就調用了幾個函數而已,這有啥好寫的?不過想了想,還是可以介紹一下 LRU 算法的原理及簡單的用法。
 
LRU Least Recently Used, 最近最少使用)是一種內存頁面置換算法。什么叫內存頁面置換?我們知道,相對於內存的速度來講,磁盤的速度是很慢的。我們需要查詢數據的時候,不能每次都跑到磁盤去查,需要在內存里設置一塊空間,把一些常用的數據放在這塊空間里,以后查的時候就直接在這里查,而不必去磁盤,從而起到“加速”的作用。但是這塊空間肯定是遠遠小於磁盤大小的。那么什么樣的數據放在這里才合適呢?當然是常用的數據。那什么樣的數據是“常用”的數據呢?這里就有幾種策略了。比如最簡單FIFO(先進先出),RR(時間片輪轉)等等,當然這就是我們最熟悉的隊列和堆棧的做法。LRU也是這樣一種策略,它的思想是基於這樣一種觀察和假定:最近經常訪問的數據,在所有數據中也是最常訪問的。所以,在這樣一塊空間中,最近被訪問過的頁面被當做“頻繁訪問”的,而一直沒有被訪問過的則被替換出去。這種思想是操作系統存儲管理中最常見的方式之一,而目前也被廣泛的應用為“緩存”的概念。緩存思想應用的也是相當廣泛的,比如寄存器,比如內存,還有網絡、數據庫、IO等等方面,只要有輸入/輸出速度不匹配的地方,緩存就可以作為強有力的武器。
 
扯的有點遠。接下來講講LRU算法的原理吧。假設我們開了可憐的一小塊空間作為緩存,只能存5個數,頁面編號為0,1,2,3,4。然后需要查詢的一串序列為:4,7,0,7,1,0,1,2,1,2,6。那么將會出現如下圖所示的情況:
整個查詢過程為:
查詢4,緩存中不存在,到磁盤中查,並把4放在緩存中;
查詢7,類似上面的情況;
查詢0,類似上面的情況;
查詢7,直接在緩存中查到了,那么7作為“最近”查過的數據,放在最新的位置;
查詢1,緩存中不存在,到磁盤中查,並把4放在緩存中;
查詢0,直接在緩存中查到了,那么0作為“最近”查過的數據,放在最新的位置;
。。。。。。
后面依此類推。
 
現在大概清楚LRU是個怎樣的算法,以及為什么可以作為緩存來使用了吧。這里有一篇文章分析的不錯,可以參考一下: 圖解緩存淘汰算法一之LRU
現在我的項目中需要用到緩存了,可是忘了名字,只記得大概的原理,就去群里問道: 我需要這樣一個數據結構,查詢效率高,類似字典和隊列,但最近訪問過的數據最后出隊,很久沒有訪問過的數據就先被踢出去。群里大神指點我去看看LRUCache,恍然大悟,就是這個名字!於是百度了一下,結果找到了不少原理和java實現(比如  http://dennis-zane.iteye.com/blog/128278),就是沒看到python的。於是到群里請教大神,大神一語中的:pylru。又去百度了一下,果然有這東西!
pylru可以使用pip安裝,可以到pypi上查看下載及使用方法: https://pypi.python.org/pypi/pylru/1.0.9  使用起來又炒雞簡單,按某人的話來說就是:你們python真不要臉。
這個庫是純粹用python寫的,有興趣可以看看它的實現。庫十分短小精悍,只有幾百行代碼,注釋還占了一多半。
 
測試:
有點啰嗦了,不過這樣結果也很清楚。
如果將來涉及到要寫緩存了,能想起來這個東西,就是幸運。這也是我們為什么建議掌握一定的算法基礎,以及操作系統、體系結構等基礎課程的原因:並不是在實踐中讓你真的去寫一個排序算法,寫一個緩存,而是當你在某種場合下,能突然意識到:這特么不就是個XXX算法嗎,我以前接觸過的。比自己吭哧吭哧半天寫出來個詭異的數據結構要好的多。
 
本文參考:
1、《現代操作系統》第四章:存儲管理:4.4:頁面置換算法
3、360圖書館:圖解緩存淘汰算法一之LRU : http://www.360doc.com/content/14/0704/09/10504424_391894263.shtml
4、ITEye:LRUCache的java版本實現: http://dennis-zane.iteye.com/blog/128278
5、PyPI:pylru下載及使用: https://pypi.python.org/pypi/pylru/1.0.9


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM