Python functools.lru_cache自動緩存應(yīng)用小結(jié)
基本介紹
lru_cache是Python3.2版本在functools標(biāo)準(zhǔn)模塊中引入的裝飾器,用于實現(xiàn)最近最少使用(Least Recently Used, LRU)緩存策略,適用于所有相同輸入對應(yīng)相同輸出的確定性函數(shù),即緩存函數(shù)的參數(shù)和返回值的映射,只要下次調(diào)用參數(shù)相同,就直接返回緩存的結(jié)果,不再執(zhí)行函數(shù)體。
工作原理:
- 緩存命中:當(dāng)使用相同的參數(shù)調(diào)用被裝飾的函數(shù)時,函數(shù)不會真正執(zhí)行,而是直接從緩存中返回結(jié)果。
- 緩存未命中:當(dāng)參數(shù)不在緩存中時,函數(shù)正常執(zhí)行,并將結(jié)果存入緩存。
- 緩存淘汰:當(dāng)緩存(不同參數(shù)個數(shù))達(dá)到設(shè)定的最大容量(由 maxsize參數(shù)指定)時,它會自動淘汰最久未被使用的結(jié)果,以控制內(nèi)存占用。
可通過參數(shù)maxsize=n指定緩存的最大容量,參數(shù)值為None表示無限制緩存,會緩存所有不同參數(shù)組合的函數(shù)返回值,性能最優(yōu)但存在內(nèi)存溢出的風(fēng)險,根據(jù)實際情況設(shè)置。
在遞歸中的應(yīng)用
lru_cache雖然適用于所有確定性的函數(shù),但在遞歸場景中使用特別合適,因為遞歸場景中往往需要重復(fù)計算相同的子問題。以下面斐波那契數(shù)列為例:
def fib(num):
if num == 0 or num == 1:
return num
return fib(num - 1) + fib(num - 2)
fib(5)對應(yīng)的遞歸樹:
fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2) f(1) f(1)f(0) f(1)f(0)
/ \
f(1) f(0)如果不使用緩存,fib(3)和fib(2)都被重復(fù)計算了多次,如果把這棵遞歸樹看成滿二叉樹,fib(n)一共有n層,每層的節(jié)點數(shù)量分別為 2 0 2^0 20, 2 1 2^1 21, 2 2 2^2 22, …, 2 n 2^n 2n, 那么總的時間復(fù)雜度 O ( 2 n ) O(2^n) O(2n)。
如果使用了lru,函數(shù)會在第一次計算矩形標(biāo)記的fib(0),fib(1),…, fib(5)時將每個參數(shù)對應(yīng)的函數(shù)值緩存,也就是對于fib(5)的整個計算流程中,標(biāo)記的6個記錄在第一次計算時未命中緩存,會執(zhí)行函數(shù)并將這6個記錄的結(jié)果緩存,在后續(xù)計算中直接讀取圓形標(biāo)記的fib(1),fib(2),fib(3)的緩存,直接讀取3次緩存就可以直接結(jié)束整個函數(shù)。

對于上面的分析可使用被裝飾函數(shù)的cache_info方法輸出詳細(xì)的緩存信息查看:
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(num):
if num == 0 or num == 1:
return num
return fib(num - 1) + fib(num - 2)
print(fib(5))
print(fib.cache_info())
被
lru_cache裝飾的函數(shù)也會自動同時綁定上cache_info方法,用于顯示整個函數(shù)計算過程中的緩存命中情況,返回4個字段,含義分別是:
1)hits:緩存命中次數(shù)
2)misses:緩存未命中次數(shù)
3)maxsize:緩存最大容量
4)currsize:當(dāng)前已緩存數(shù)量
緩存清空
lru_cache會為所有同名的函數(shù)全局維護(hù)一個獨立的緩存結(jié)構(gòu),不同函數(shù)之間的緩存空間不沖突。除非手動cache_clear,否則緩存不會自動清除。
到此這篇關(guān)于Python functools.lru_cache自動緩存應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)Python functools.lru_cache緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python+wxPython實現(xiàn)批量文件擴(kuò)展名替換
這篇文章主要介紹了如何使用 Python和wxPython創(chuàng)建一個簡單的圖形界面應(yīng)用程序,使用戶能夠選擇文件夾、輸入要替換的文件類型和新的文件類型,并實現(xiàn)批量替換文件擴(kuò)展名的功能,有需要的可以參考一下2023-10-10
Python multiprocessing 進(jìn)程間通信方式實現(xiàn)
本文主要介紹了Python multiprocessing 進(jìn)程間通信方式實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Python Pandas模塊實現(xiàn)數(shù)據(jù)的統(tǒng)計分析的方法
在上一篇講了幾個常用的“Pandas”函數(shù)之后,今天小編就為大家介紹一下在數(shù)據(jù)統(tǒng)計分析當(dāng)中經(jīng)常用到的“Pandas”函數(shù)方法,希望能對大家有所收獲,需要的朋友可以參考下2021-06-06
Python實戰(zhàn)之利用Geopandas算出每個省面積
GeoPandas是一個基于pandas,針對地理數(shù)據(jù)做了特別支持的第三方模塊。本文將利用GeoPandas計算出每個省的面積,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧2021-12-12

