如何在Python中緩存方法調(diào)用?
緩存是一種提高程序性能的一種優(yōu)化手段,通過將計(jì)算好的結(jié)果存儲(chǔ)在內(nèi)存中,當(dāng)下一次使用到相同的輸入時(shí),直接從內(nèi)存中獲取結(jié)果,避免重復(fù)計(jì)算。愛掏網(wǎng) - it200.com
Python中的緩存
在Python中,我們可以使用一些第三方庫來實(shí)現(xiàn)緩存功能,如functools
庫的lru_cache
方法和caching
庫等。愛掏網(wǎng) - it200.com下面我們分別來了解如何使用這兩種方式在Python中實(shí)現(xiàn)緩存。愛掏網(wǎng) - it200.com
functools庫的lru_cache方法
functools
庫是Python的標(biāo)準(zhǔn)庫之一,提供了許多常用的工具函數(shù)。愛掏網(wǎng) - it200.com其中lru_cache
方法可以將函數(shù)的調(diào)用結(jié)果緩存起來,避免重復(fù)計(jì)算。愛掏網(wǎng) - it200.com
假設(shè)我們要寫一個(gè)函數(shù)來計(jì)算n的階乘,遞歸式計(jì)算n!的時(shí)間復(fù)雜度為O(n),而且會(huì)出現(xiàn)大量的重復(fù)計(jì)算。愛掏網(wǎng) - it200.com這時(shí)我們就可以使用lru_cache
來緩存計(jì)算結(jié)果,提高計(jì)算效率。愛掏網(wǎng) - it200.com
import functools
@functools.lru_cache(maxsize=256)
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 120
print(factorial(10)) # 3628800
上面的代碼中,我們使用lru_cache
方法將factorial
函數(shù)的調(diào)用結(jié)果緩存起來,當(dāng)下一次調(diào)用相同的輸入時(shí),直接從緩存中獲取結(jié)果,避免重復(fù)計(jì)算。愛掏網(wǎng) - it200.com
在上面的代碼中,我們?cè)O(shè)置了maxsize=256
,表示最多存儲(chǔ)256個(gè)調(diào)用結(jié)果。愛掏網(wǎng) - it200.com如果調(diào)用次數(shù)超過了256次,那么早期的調(diào)用結(jié)果將會(huì)被丟棄,以便為新的調(diào)用結(jié)果騰出空間。愛掏網(wǎng) - it200.com
caching庫
caching
庫是一個(gè)輕量級(jí)的Python緩存庫,可以方便地對(duì)函數(shù)進(jìn)行緩存。愛掏網(wǎng) - it200.com它提供了兩種方式:內(nèi)存緩存和持久化緩存。愛掏網(wǎng) - it200.com
內(nèi)存緩存只在程序運(yùn)行期間有效,程序重啟后緩存將丟失,而持久化緩存可以將結(jié)果存儲(chǔ)在本地文件系統(tǒng)或數(shù)據(jù)庫中,即使程序重啟也可以從緩存中讀取結(jié)果。愛掏網(wǎng) - it200.com
在下面的例子中,我們展示了如何使用內(nèi)存緩存和持久化緩存來緩存函數(shù)調(diào)用結(jié)果。愛掏網(wǎng) - it200.com
內(nèi)存緩存
from caching import cached
@cached()
def fibonacci(n):
if n in (0, 1):
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10)) # 55
print(fibonacci(20)) # 6765
上面的代碼中,我們使用cached
裝飾器將fibonacci
函數(shù)的調(diào)用結(jié)果緩存到內(nèi)存中,下次調(diào)用相同的輸入時(shí),直接從緩存中獲取結(jié)果。愛掏網(wǎng) - it200.com
持久化緩存
當(dāng)內(nèi)存緩存的大小有限時(shí),如果緩存空間不足,早期的結(jié)果將會(huì)被丟棄。愛掏網(wǎng) - it200.com這時(shí)我們可以使用持久化緩存來存儲(chǔ)結(jié)果,以便長(zhǎng)期保存。愛掏網(wǎng) - it200.com
from caching import cached
@cached(cache='file', expire=60)
def fibonacci(n):
if n in (0, 1):
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10)) # 55
print(fibonacci(20)) # 6765
上面的代碼中,我們使用cached
裝飾器將fibonacci
函數(shù)的調(diào)用結(jié)果緩存到文件系統(tǒng)中,過期時(shí)間為60秒。愛掏網(wǎng) - it200.com當(dāng)60秒后再次調(diào)用相同的輸入時(shí),將會(huì)重新計(jì)算,重新緩存結(jié)果。愛掏網(wǎng) - it200.com
緩存的注意事項(xiàng)
在使用緩存時(shí),需要考慮以下幾點(diǎn):
緩存的命中率
緩存的命中率表示緩存結(jié)果被使用的比率,命中率越高,說明緩存效果越好。愛掏網(wǎng) - it200.com為了提高緩存的命中率,需要選取恰當(dāng)?shù)木彺娌呗院途彺娲笮 ?b class="xhide">愛掏網(wǎng) - it200.com
緩存的過期時(shí)間
緩存的過期時(shí)間指的是緩存結(jié)果的有效期限,過期后需要重新計(jì)算。愛掏網(wǎng) - it200.com為了避免使用過期的緩存結(jié)果,需要設(shè)置合適的過期時(shí)間,并定時(shí)刷新緩存。愛掏網(wǎng) - it200.com