python中functools.lru_cache的具體使用
1. 優(yōu)化算法的思想
當(dāng)算法的復(fù)雜度較高時(shí),常見(jiàn)的優(yōu)化策略包括:
- 減少重復(fù)計(jì)算:通過(guò)緩存結(jié)果避免相同輸入的重復(fù)計(jì)算。這種方法常用在遞歸和動(dòng)態(tài)規(guī)劃問(wèn)題中。
- 合理使用數(shù)據(jù)結(jié)構(gòu):根據(jù)具體問(wèn)題,選擇合適的數(shù)據(jù)結(jié)構(gòu)(如哈希表、堆、樹(shù)等),以提高操作效率。例如,用哈希表可以加快查找操作。
- 剪枝(Pruning):在搜索或遞歸算法中,及時(shí)放棄不可能產(chǎn)生最優(yōu)解的分支,減少無(wú)效計(jì)算。
- 分治法(Divide and Conquer):將大問(wèn)題拆解為多個(gè)小問(wèn)題,分別求解后再合并結(jié)果。經(jīng)典例子是歸并排序。
- 記憶化(Memoization):將已經(jīng)計(jì)算過(guò)的結(jié)果保存下來(lái),以便下次直接使用。這種策略在遞歸或遞推中尤為重要。
- 動(dòng)態(tài)規(guī)劃(Dynamic Programming):通過(guò)存儲(chǔ)子問(wèn)題的結(jié)果,避免重復(fù)計(jì)算子問(wèn)題。
2. LRU 算法與優(yōu)化思想的關(guān)系
LRU(Least Recently Used,最近最少使用) 是一種基于 緩存優(yōu)化 思想的算法,用于減少重復(fù)計(jì)算。這與上面的減少重復(fù)計(jì)算思想緊密相關(guān)。LRU 通過(guò)緩存結(jié)果來(lái)加速訪問(wèn),但同時(shí)通過(guò)淘汰最近最少使用的緩存項(xiàng)來(lái)保證緩存不會(huì)無(wú)限增長(zhǎng)。
LRU 算法的核心思想:
- 保留最近使用的結(jié)果,淘汰不常用的結(jié)果。
- 如果緩存容量達(dá)到上限,優(yōu)先淘汰最久未被使用的項(xiàng)。
3. functools.lru_cache
Python 提供了 functools.lru_cache
,這是一個(gè)基于 LRU 算法的緩存裝飾器。它會(huì)緩存函數(shù)的返回值,當(dāng)再次調(diào)用該函數(shù)時(shí),如果參數(shù)相同,直接從緩存中返回結(jié)果,避免重復(fù)計(jì)算。lru_cache
自動(dòng)處理 LRU 淘汰策略,能夠顯著優(yōu)化那些需要大量重復(fù)計(jì)算的場(chǎng)景。
lru_cache 的參數(shù)
maxsize
:緩存的最大容量,超過(guò)這個(gè)容量時(shí),最近最少使用的數(shù)據(jù)會(huì)被淘汰。maxsize=None
表示沒(méi)有限制。typed
:若設(shè)置為True
,不同類型的相同值將被區(qū)別對(duì)待。例如1
和1.0
會(huì)被認(rèn)為是不同的參數(shù)。
4. 原理詳解:functools.lru_cache 是如何工作的?
- 緩存機(jī)制:當(dāng)你第一次調(diào)用某個(gè)函數(shù)時(shí),它的計(jì)算結(jié)果會(huì)被緩存起來(lái),儲(chǔ)存在一個(gè)類似字典的結(jié)構(gòu)中。
- 緩存命中:當(dāng)你再次調(diào)用該函數(shù),且參數(shù)相同時(shí),函數(shù)不會(huì)再次執(zhí)行,而是直接返回緩存中的結(jié)果。
- 緩存淘汰:如果緩存的數(shù)量達(dá)到了
maxsize
,并且有新的函數(shù)調(diào)用進(jìn)入緩存,則最近最少被使用的緩存項(xiàng)會(huì)被淘汰。
5. 如何使用 functools.lru_cache 優(yōu)化算法
接下來(lái)通過(guò)一些例子說(shuō)明如何結(jié)合 functools.lru_cache
和 LRU 算法來(lái)優(yōu)化算法。
示例 1:優(yōu)化遞歸算法(斐波那契數(shù)列)
未優(yōu)化的版本(時(shí)間復(fù)雜度為 O(2^n))
def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) print(fibonacci(30)) # 計(jì)算非常慢,因?yàn)榇嬖诖罅恐貜?fù)計(jì)算
優(yōu)化后的版本(使用 functools.lru_cache
)
from functools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) print(fibonacci(30)) # 速度快得多,因?yàn)楸苊饬酥貜?fù)計(jì)算
maxsize=128
:表示最多緩存 128 個(gè)結(jié)果,超出部分將按 LRU 策略淘汰。
示例 2:帶不同參數(shù)類型的緩存
@lru_cache(maxsize=100, typed=True) def double(x): return x * 2 print(double(1)) # 緩存 1 的結(jié)果 print(double(1.0)) # 緩存 1.0 的結(jié)果,區(qū)別對(duì)待
這里 typed=True
意味著 double(1)
和 double(1.0)
是不同的緩存條目,雖然它們的值相同,但類型不同。
示例 3:緩存大規(guī)模計(jì)算結(jié)果
假設(shè)我們有一個(gè)耗時(shí)的計(jì)算,比如對(duì)一個(gè)大數(shù)組的求和操作:
import time @lru_cache(maxsize=32) def expensive_sum(arr): time.sleep(2) # 模擬耗時(shí)操作 return sum(arr) arr = tuple(range(1000000)) # 第一次調(diào)用 print(expensive_sum(arr)) # 需要等待 2 秒 # 第二次調(diào)用(相同的參數(shù)) print(expensive_sum(arr)) # 立即返回結(jié)果,無(wú)需等待
由于 arr
是相同的參數(shù),第二次調(diào)用時(shí)直接從緩存中獲取結(jié)果。
總結(jié)
- 優(yōu)化思想:常見(jiàn)的優(yōu)化策略包括減少重復(fù)計(jì)算、合理使用數(shù)據(jù)結(jié)構(gòu)、動(dòng)態(tài)規(guī)劃等。
- LRU 算法:是一種緩存淘汰算法,主要用于緩存系統(tǒng)中,通過(guò)淘汰最近最少使用的緩存項(xiàng),優(yōu)化重復(fù)計(jì)算問(wèn)題。
functools.lru_cache
:是 Python 提供的基于 LRU 算法的緩存工具,用于減少函數(shù)的重復(fù)計(jì)算,自動(dòng)管理緩存。- 應(yīng)用場(chǎng)景:可以用于遞歸、動(dòng)態(tài)規(guī)劃、I/O 緩存等需要重復(fù)調(diào)用的場(chǎng)景。
通過(guò) functools.lru_cache
,你可以輕松優(yōu)化具有重復(fù)計(jì)算的函數(shù),大大提高代碼的執(zhí)行效率。
到此這篇關(guān)于python中functools.lru_cache的具體使用的文章就介紹到這了,更多相關(guān)python functools.lru_cache內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python爬蟲(chóng)抓取論壇關(guān)鍵字過(guò)程解析
這篇文章主要介紹了Python爬蟲(chóng)抓取論壇關(guān)鍵字過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Pytest測(cè)試報(bào)告工具Allure的高級(jí)用法
這篇文章介紹了Pytest測(cè)試報(bào)告工具Allure的高級(jí)用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07Python調(diào)用Java可執(zhí)行jar包問(wèn)題
這篇文章主要介紹了Python調(diào)用Java可執(zhí)行jar包問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Python collections.deque雙邊隊(duì)列原理詳解
這篇文章主要介紹了Python collections.deque雙邊隊(duì)列原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Python實(shí)現(xiàn)將wav轉(zhuǎn)amr,并轉(zhuǎn)換成hex數(shù)組
這篇文章主要介紹了Python實(shí)現(xiàn)將wav轉(zhuǎn)amr,并轉(zhuǎn)換成hex數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05修復(fù)Python?Pandas數(shù)據(jù)標(biāo)記錯(cuò)誤的幾種方法總結(jié)
用于分析數(shù)據(jù)的?Python?庫(kù)稱為?Pandas,在?Pandas?中讀取數(shù)據(jù)最常見(jiàn)的方式是通過(guò)?CSV?文件,但?CSV?文件的限制是它應(yīng)該采用特定的格式,否則在標(biāo)記數(shù)據(jù)時(shí)會(huì)拋出錯(cuò)誤,在本文中,我們將討論修復(fù)?Python?Pandas?錯(cuò)誤標(biāo)記數(shù)據(jù)的各種方法2023-10-10