當前位置:首頁 » 文件管理 » python模擬帶時間緩存

python模擬帶時間緩存

發布時間: 2024-09-18 18:30:55

python性能提升神器!lru_cache的介紹和講解

我們經常談論的緩存一詞,更多的類似於將硬碟中的數據存放到內存中以至於提高讀取速度,比如常說的redis,就經常用來做數據的緩存。 Python的緩存(lru_cache)是一種裝飾在被執行的函數上,將其執行的結果緩存起來,當下次請求的時候,如果請求該函數的傳參未變則直接返回緩存起來的結果而不再執行函數的一種緩存裝飾器。

那它和redis的區別在哪?有什麼優勢?怎麼使用? 下面為你講解

1.現在我們先不使用緩存來寫一個求兩數之和的函數,並調用執行它兩次:

執行結果

可以看到 test 被執行了兩次,現在我們加上緩存再進行執行:

執行結果

可以看到 test 函數只被執行了一次,第二次的調用直接輸出了結果,使用了緩存起來的值。

2.當我們使用遞歸求斐波拉契數列 (斐波那契數列指的是這樣一個數列:0,1,1,2,3,5,8,它從第3項開始,每一項都等於前兩項之和) 的時候,緩存對性能的提升就尤其明顯了:

不使用緩存求第40項的斐波拉契數列

執行時間

使用緩存求第40項的斐波拉契數列:

執行時間

兩個差距是非常明顯的,因為不使用緩存時,相當於要重復執行了很多的函數,而使用了 lru_cache 則把之前執行的函數結果已經緩存了起來,就不需要再次執行了。

查看lru_cache源碼會發現它可以傳遞兩個參數: maxsize 、 typed :

代表被lru_cache裝飾的方法最大可緩存的結果數量 (被裝飾方法傳參不同一樣,則結果不一樣;如果傳參一樣則為同一個結果) , 如果不指定傳參則默認值為128,表示最多緩存128個返回結果,當達到了128個時,有新的結果要保存時,則會刪除最舊的那個結果。如果maxsize傳入為None則表示可以緩存無限個結果;

默認為false,代表不區分數據類型,如果設置為True,則會區分傳參類型進行緩存,官方是這樣描述的:

但在python3.9.8版本下進行測試,typed為false時,按照官方的測試方法測試得到的還是會被當成不同的結果處理,這個時候typed為false還是為true都會區別緩存,這與官方文檔的描述存在差異:

執行結果

但如果是多參數的情況下,則會被當成一個結果:

執行結果

這個時候設置typed為true時,則會區別緩存:

執行結果

當傳參個數大於1時,才符合官方的說法,不清楚是不是官方舉例有誤

當傳遞的參數是dict、list等的可變參數時,lru_cache是不支持的,會報錯:

報錯結果

緩存 緩存位置 是否支持可變參數 是否支持分布式 是否支持過期時間設置 支持的數據結構 需單獨安裝 redis 緩存在redis管理的內存中 是 是 是 支持5種數據結構 是 lru_cache 緩存在應用進程的內存中,應用被關閉則被清空 否 否 否 字典(參數為:key,結果為:value) 否

經過上面的分析,lru_cache 功能相對於redis來說要簡單許多,但使用起來更加方便,適用於小型的單體應用。如果涉及的緩存的數據種類比較多並且想更好的管理緩存、或者需要緩存數據有過期時間(類似登錄驗證的token)等,使用redis是優於lru_cache的。

❷ 我用python寫了一個腳本,是每隔30秒清理arp緩存,這樣能夠控制arp攻擊嗎求高手指教

不能。新的假arp信息來了,你還是會緩存錯的mac地址啊。

❸ 軟體開發模版緩存具體步驟怎麼操作的呢

模板緩存就是把模版內容緩存到指定位置,只要涉及模版都可以設置緩存,

下面以py程序為例:
1.1 在導入搜索期間首先會被檢查的地方是 sys.moles。 這個映射起到緩存之前導入的所有模塊的作用(包括其中間路徑)。 因此如果之前導入過 foo.bar.baz,則 sys.moles 將包含 foo, foo.bar 和 foo.bar.baz 條目。 每個鍵的值就是相應的模塊對象。
在導入期間,會在 sys.moles 查找模塊名稱,如存在則其關聯的值就是需要導入的模塊,導入過程完成。 然而,如果值為 None,則會引發 MoleNotFoundError。 如果找不到指定模塊名稱,Python 將繼續搜索該模塊。
1.2 sys.moles 是可寫的。刪除鍵可能不會破壞關聯的模塊(因為其他模塊可能會保留對它的引用),但它會使命名模塊的緩存條目無效,導致 Python 在下次導入時重新搜索命名模塊。鍵也可以賦值為 None ,強制下一次導入模塊導致 MoleNotFoundError 。
但是要小心,因為如果你還保有對某個模塊對象的引用,同時停用其在 sys.moles 中的緩存條目,然後又再次導入該名稱的模塊,則前後兩個模塊對象將 不是 同一個。 相反地,

1.3 importlib.reload() 將重用 同一個 模塊對象,並簡單地通過重新運行模塊的代碼來重新初始化模塊內容。

1.1 在導入搜索期間首先會被檢查的地方是 sys.moles。 這個映射起到緩存之前導入的所有模塊的作用(包括其中間路徑)。 因此如果之前導入過 foo.bar.baz,則 sys.moles 將包含 foo, foo.bar 和 foo.bar.baz 條目。 每個鍵的值就是相應的模塊對象。
在導入期間,會在 sys.moles 查找模塊名稱,如存在則其關聯的值就是需要導入的模塊,導入過程完成。 然而,如果值為 None,則會引發 MoleNotFoundError。 如果找不到指定模塊名稱,Python 將繼續搜索該模塊。
1.2 sys.moles 是可寫的。刪除鍵可能不會破壞關聯的模塊(因為其他模塊可能會保留對它的引用),但它會使命名模塊的緩存條目無效,導致 Python 在下次導入時重新搜索命名模塊。鍵也可以賦值為 None ,強制下一次導入模塊導致 MoleNotFoundError 。
但是要小心,因為如果你還保有對某個模塊對象的引用,同時停用其在 sys.moles 中的緩存條目,然後又再次導入該名稱的模塊,則前後兩個模塊對象將 不是 同一個。 相反地,

1.3 importlib.reload() 將重用 同一個 模塊對象,並簡單地通過重新運行模塊的代碼來重新初始化模塊內容。

❹ Python 爬蟲進階篇——diskcahce緩存(二)

上一篇文章為大家介紹了diskcache的基礎用法,本文將繼續深入探討diskcache的更多高級功能。

關於diskcache,它是一種基於SQLite資料庫的緩存對象管理方式。SQLite是一個輕量級的基於磁碟的資料庫,它不需要單獨的伺服器進程,並支持SQL查詢。在上篇文章的源碼截圖上,你可以看到一些SQL語句的使用。

diskcache支持使用diskcache.FanoutCache自動分片基礎資料庫。分片是對數據進行水平分區,可以減少寫入時的阻塞。盡管讀和寫不會互相阻礙,但寫入會阻礙其他寫入。分片的默認值為8。

以下是一個示例代碼:

# 示例代碼

在示例中,我們在diskcache_2文件夾中創建了一個具有四個分片和一秒超時的緩存。如果操作耗時超過一秒,它們將嘗試中止操作。

那麼每一個分片的大小是多少呢?分片的大小都是平均分配的,占總空間的四分之一。diskcache的默認大小為1GB。

diskcache提供了一個collections.deque兼容的雙端隊列diskcache.Deque。雙端隊列是堆棧和隊列的一般化,可以在前後都可以進行快速訪問和編輯,且可持久化,操作比較便捷。

以下是一個示例代碼:

# 示例代碼

運行結果如下:

Popleft 獲取隊列最前面的一個元素,pop獲取末尾的一個元素;

Appendleft 在隊列最開始添加一個元素,append 在末尾添加一個元素;

Extendleft 在隊列最開始添加一個數組,extend在末尾添加一個數組;

那麼deque的存儲位置在哪裡?可以使用以下命令查看隊列的存儲位置:

包括cache也是一個可以使用directory屬性查看默認存儲的位置;

那麼如何指定directory呢?Deque的第二個參數指定存儲位置,第一個參數為隊列的初始值。或者可以直接指定參數名稱,如下:

Index 類似於dict(字典),可持久化,使用也比較便捷。以下是一個示例:

# 示例代碼

popitem表示獲取最後一個鍵對值,並且刪除,結果如下:

peekitem() 可傳遞last 參數是否獲取最後一個,不會刪除原始值;

setdefault(key,default) 可以給指定的key值設置默認值,在查找時可以預先設置一個默認值,防止key值不存在而拋出異常。

keys()與values()可以查找所有Index中的key值與value值,然而沒有提供判斷key值是否存在的方法,但是可以使用setdefault的方法自行封裝。

Lock還記得上篇文章中提到的Lock鎖嗎?先看一下源碼:

可以看到這里的鎖用的就是cache的add方法的特性,源碼中也給出了使用的方式:

從源碼上看有一個while 死循環,直到add成功時才會被釋放,這里處理的方式不是很好,可能會造成死鎖,所以一般情況下,都會添加一個過期的時間,如下:

RLock還有一種RLock鎖,與Lock鎖的區別是RLock允許在同一線程中被多次acquire。而Lock卻不允許這種情況。以下是一個示例:

結果是執行成功。

看一下源碼:

從源碼中可以看出,判斷鎖的條件是os.getpid()(進程pid)與threading.get_ident()(線程標識符),如果每次acquire時的pid與ident都相同的時,即可成功。那麼就可以在相同的進程中無限次數的acquire,但是多少次acquire就得多少次的release,防止死鎖。

那麼是使用Lock還是RLock呢?這個要具體的看實際情況,並不是誰就一定好。

總結本次推文中介紹了diskcache中FanoutCache緩存分片、雙端隊列deque、Index、Lock以及RLock。

大家可以在實際中靈活運用,diskcache緩存的優勢還是很大的,無需安裝其他的模塊,並且在文件管理器中能直接查看,還可以利用緩存的一些特性使用多線程的去實現業務等。

但是也是有缺點的,即受制於本地文件系統的限制。每個磁碟每個目錄下的文件數量是有限制的,所以需要結合實際情況使用。

熱點內容
軟體連不上伺服器ip 發布:2024-09-19 19:15:49 瀏覽:722
伺服器資料庫如何建立 發布:2024-09-19 19:15:07 瀏覽:365
解壓軟體游戲 發布:2024-09-19 18:51:54 瀏覽:155
16新速騰配置怎麼樣有改進嗎 發布:2024-09-19 18:47:20 瀏覽:338
腳本不管用 發布:2024-09-19 18:46:30 瀏覽:98
科學計算編程 發布:2024-09-19 18:46:29 瀏覽:758
由你定製源碼 發布:2024-09-19 18:40:31 瀏覽:574
dz論壇資料庫 發布:2024-09-19 18:40:20 瀏覽:711
北京一建密碼鎖哪裡買 發布:2024-09-19 18:39:01 瀏覽:79
安卓打拳王哪個平台好 發布:2024-09-19 18:27:30 瀏覽:294