您好,登錄后才能下訂單哦!
這篇文章主要講解了“Python中緩存lru_cache的方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python中緩存lru_cache的方法是什么”吧!
我們經常談論的緩存一詞,更多的類似于將硬盤中的數據存放到內存中以至于提高讀取速度,比如常說的redis,就經常用來做數據的緩存。
Python的緩存(lru_cache)是一種裝飾在被執行的函數上,將其執行的結果緩存起來,當下次請求的時候,如果請求該函數的傳參未變則直接返回緩存起來的結果而不再執行函數的一種緩存裝飾器。
1.現在我們先不使用緩存來寫一個求兩數之和的函數,并調用執行它兩次:
def test(a, b): print('開始計算a+b的值...') return a + b print('1+2等于:', test(1, 2)) print('1+2等于:', test(1, 2))
執行結果
開始計算a+b的值...
1+2等于: 3
開始計算a+b的值...
1+2等于: 3
可以看到test被執行了兩次,現在我們加上緩存再進行執行:
from functools import lru_cache @lru_cache def test(a, b): print('開始計算a+b的值...') return a + b print(test(1, 2)) print(test(1, 2))
執行結果
開始計算a+b的值...
1+2等于: 3
1+2等于: 3
可以看到test函數只被執行了一次,第二次的調用直接輸出了結果,使用了緩存起來的值。
2.當我們使用遞歸求斐波拉契數列 (斐波那契數列指的是這樣一個數列:0,1,1,2,3,5,8,它從第3項開始,每一項都等于前兩項之和) 的時候,緩存對性能的提升就尤其明顯了:
不使用緩存求第40項的斐波拉契數列
import datetime def fibonacci(num): # 不使用緩存時,會重復執行函數 return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2) start = datetime.datetime.now() print(fibonacci(40)) end = datetime.datetime.now() print('執行時間', end - start)
執行時間
執行時間 0:00:29.004424
使用緩存求第40項的斐波拉契數列:
import datetime def fibonacci(num): # 不使用緩存時,會重復執行函數 return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2) start = datetime.datetime.now() print(fibonacci(40)) end = datetime.datetime.now() print('執行時間', end - start)
執行時間
執行時間 0:00:00
兩個差距是非常明顯的,因為不使用緩存時,相當于要重復執行了很多的函數,而使用了lru_cache則把之前執行的函數結果已經緩存了起來,就不需要再次執行了。
查看lru_cache源碼會發現它可以傳遞兩個參數:maxsize、typed:
def lru_cache(maxsize=128, typed=False): """Least-recently-used cache decorator. If *maxsize* is set to None, the LRU features are disabled and the cache can grow without bound. ... """
1) maxsize
代表被lru_cache裝飾的方法最大可緩存的結果數量 (被裝飾方法傳參不同一樣,則結果不一樣;如果傳參一樣則為同一個結果), 如果不指定傳參則默認值為128,表示最多緩存128個返回結果,當達到了128個時,有新的結果要保存時,則會刪除最舊的那個結果。如果maxsize傳入為None則表示可以緩存無限個結果;
2)typed
默認為false,代表不區分數據類型,如果設置為True,則會區分傳參類型進行緩存,官方是這樣描述的:
如果typed為True,則將分別緩存不同類型的參數,
例如,f(3.0)和f(3)將被視為具有明顯的結果。
但在python3.9.8版本下進行測試,typed為false時,按照官方的測試方法測試得到的還是會被當成不同的結果處理,這個時候typed為false還是為true都會區別緩存,這與官方文檔的描述存在差異:
from functools import lru_cache @lru_cache def test(a): print('函數被調用了...') return a print(test(1.0)) print(test(1))
執行結果
函數被調用了...
1.0
函數被調用了...
但如果是多參數的情況下,則會被當成一個結果:
from functools import lru_cache @lru_cache def test(a, b): print('函數被調用了...') return a , b print(test(1.0, 2.0)) print(test(1, 2))
執行結果
函數被調用了...
(1.0, 2.0)
(1.0, 2.0)
這個時候設置typed為true時,則會區別緩存:
from functools import lru_cache @lru_cache(typed=True) def test(a, b): print('函數被調用了...') return a , b print(test(1.0, 2.0)) print(test(1, 2))
執行結果
函數被調用了...
(1.0, 2.0)
函數被調用了...
(1, 2)
當傳參個數大于1時,才符合官方的說法,不清楚是不是官方舉例有誤
當傳遞的參數是dict、list等的可變參數時,lru_cache是不支持的,會報錯:
from functools import lru_cache @lru_cache def test(a): print('函數被執行了...') return a print(test({'a':1}))
報錯結果
TypeError: unhashable type: 'dict'
緩存 | 緩存位置 | 是否支持可變參數 | 是否支持分布式 | 是否支持過期時間設置 | 支持的數據結構 | 需單獨安裝 |
---|---|---|---|---|---|---|
redis | 緩存在redis管理的內存中 | 是 | 是 | 是 | 支持5種數據結構 | 是 |
lru_cache | 緩存在應用進程的內存中,應用被關閉則被清空 | 否 | 否 | 否 | 字典(參數為:key,結果為:value) | 否 |
感謝各位的閱讀,以上就是“Python中緩存lru_cache的方法是什么”的內容了,經過本文的學習后,相信大家對Python中緩存lru_cache的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。