[Python]使用memory_profiler測試優化前後的程式記憶體使用量

更新於 2024/09/14閱讀時間約 1 分鐘

通過 memory_profiler 來測試優化前後的程式。

上一篇memory_profiler工具的說明介紹


以下是一個記憶體使用量較高的原始程式碼,接著對程式進行優化後,再次使用 memory_profiler 來比較優化前後的記憶體使用情況。

Python版本

3.11.3

1. 原始程式碼:未經優化

這個範例創建了多個大型列表來模擬高記憶體消耗,並展示如何使用 ,執行時間非常久請小心服用

memory_profiler 來分析每一行程式碼的記憶體使用情況。

from memory_profiler import profile

@profile
def create_large_list():
a = [i for i in range(10**7)] # 大列表佔用大量記憶體
b = [i * 2 for i in a] # 創建另一個大列表
c = a.copy() # 複製列表
return b, c

if __name__ == '__main__':
create_large_list()

解析:

  • 這段程式創建了一個包含 1000 萬個元素的列表 a,然後用它來創建另一個大列表 bc。這些操作會耗費大量記憶體。
  • 運行這段程式時,使用 memory_profiler 可以查看每一步操作的記憶體增長情況。

運行命令:

python -m memory_profiler your_script.py

2. 優化後程式碼:減少記憶體使用

在這裡,我們將通過一些方法來優化記憶體使用。比如,使用生成器(generator)來避免同時在記憶體中保留多個大型列表。

from memory_profiler import profile

# 使用生成器來優化記憶體
@profile
def create_large_list_optimized():
a = (i for i in range(10**7)) # 使用生成器而不是列表
b = (i * 2 for i in a) # 生成器來避免創建大列表
return b

if __name__ == '__main__':
create_large_list_optimized()

解析:

  • 這段程式使用了生成器表達式 (i for i in range(10**7)),來取代列表,生成器是惰性評估的,因此不會立即佔用大量記憶體,而是按需生成元素。
  • 生成器的「惰性評估」(也叫延遲求值)指的是生成器不會一次性生成所有結果,而是按需生成,也就是當你需要一個值時,它才計算並返回這個值,而不會提前計算或佔用額外的記憶體。
  • 這樣的優化大幅度降低了程式的記憶體使用量,特別是在處理大型數據時。

3. 比較優化前後的記憶體使用

使用 memory_profiler 來比較優化前後的記憶體使用情況:

優化前(未使用生成器)的輸出:

raw-image

優化後(使用生成器)的輸出:

raw-image

效益分析

  • 未優化版本:每次創建或複製列表時,記憶體的增量非常大(每次增加約 431.1MiB)。如果處理更大的數據集,這樣的記憶體的佔用會迅速增長。
  • 優化後版本:使用生成器後,記憶體使用幾乎沒有增加,因為生成器不會一次性將數據載入記憶體,而是隨需求逐步生成數據。

負值說明

  • 優化前(未使用生成器)的輸出:Line #5Line #6 顯示負的記憶體增量(-2526.2 MiB-17960.5 MiB),這是異常的情況。通常,這樣的負數是由於記憶體計算的誤差或者是Python分配和釋放記憶體機制的結果導致的。

可能的原因:

  1. Python 記憶體管理:Python 有自己的記憶體分配和釋放機制,尤其是垃圾回收系統。當你創建大數據結構時,Python 可能會隨著垃圾回收系統的運行,釋放不再使用的記憶體,導致計算出現這樣的異常結果。
  2. 系統記憶體波動:有時候系統的記憶體分配和釋放過程中也會出現一些波動,特別是在運行大規模記憶體操作時,可能會導致 memory_profiler 讀取記憶體的數據不穩定。


謝謝大家觀看,若喜歡的話,希望可以追蹤,點愛心給予鼓勵

[Python]使用memory_profiler測量 Python程式記憶體使用情況

avatar-img
128會員
209內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
螃蟹_crab的沙龍 的其他內容
memory_profiler 是一個用來測量 Python 程式記憶體使用情況的工具,它可以幫助開發者了解程式的記憶體消耗,特別是在執行長時間運行或處理大量數據的程式時非常有用。 有別於tracemalloc模組,memory_profiler能在每一行程式碼上顯示記憶體變化,但相對的就不適合埋
有別於先前利用time模組做成裝飾器計算程式執行的時間,Python 標準庫中的timeit 模組是專門用來測量小段程式碼的執行時間。 [Python][裝飾器]計算函式(CT)處理時間 這篇文章將介紹如何使用 timeit.timeit() 函數,並提供一些範例來展示它的應用。
re 模組基本介紹 re 模組是 Python 用來處理正則表達式的標準模組。 正則表達式是一種用於描述字串模式的語法,可以用來匹配、搜尋、分割和替換字串中的特定模式。
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
在實務上,若Python報錯時,若引入的套件越多伴隨的異常訊息會變得越來越複雜,看到一推密密麻麻的內容時,很多時候都想直接跳過。 本文將利用Traceback來讓異常訊息變得更好理解。
當我們在做很多處理時,結果可能會是List包住一些數值,例如找輪廓或連通域分析時,沒有剛好的特徵可能就會有List含(空值得)形式出現。 為了避免報錯,我們就要額外先做一些處理,先做判斷是否有值在往下一個階段。 all 和 any 是 Python 中用於檢查可迭代物件(如清單、元組、集合等)
memory_profiler 是一個用來測量 Python 程式記憶體使用情況的工具,它可以幫助開發者了解程式的記憶體消耗,特別是在執行長時間運行或處理大量數據的程式時非常有用。 有別於tracemalloc模組,memory_profiler能在每一行程式碼上顯示記憶體變化,但相對的就不適合埋
有別於先前利用time模組做成裝飾器計算程式執行的時間,Python 標準庫中的timeit 模組是專門用來測量小段程式碼的執行時間。 [Python][裝飾器]計算函式(CT)處理時間 這篇文章將介紹如何使用 timeit.timeit() 函數,並提供一些範例來展示它的應用。
re 模組基本介紹 re 模組是 Python 用來處理正則表達式的標準模組。 正則表達式是一種用於描述字串模式的語法,可以用來匹配、搜尋、分割和替換字串中的特定模式。
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
在實務上,若Python報錯時,若引入的套件越多伴隨的異常訊息會變得越來越複雜,看到一推密密麻麻的內容時,很多時候都想直接跳過。 本文將利用Traceback來讓異常訊息變得更好理解。
當我們在做很多處理時,結果可能會是List包住一些數值,例如找輪廓或連通域分析時,沒有剛好的特徵可能就會有List含(空值得)形式出現。 為了避免報錯,我們就要額外先做一些處理,先做判斷是否有值在往下一個階段。 all 和 any 是 Python 中用於檢查可迭代物件(如清單、元組、集合等)
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
上兩篇有關List的文章,此篇文上兩章的延續,整理一些常用的方法和操作。 [Python]List(列表)新增、修改、刪除元素 [Python基礎]容器 list(列表),tuple(元組) 還有一些常用的 list 方法和操作,讓你能更靈活地處理列表數據
Thumbnail
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
此篇文章連結 RAM 與 C語言陣列的關係並提供陣列與for-loop 使用的相關教學 前半段為基本電腦觀念、後半段為實作能力的教學
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
工具功能 (1) 彈性任意查詢檔案,如對來源目錄設定,檔案修改日期 設定,檔名特定字串或副檔名設定後,自動查出明細,並可展開至各階子目錄處理     (2) 依查詢後結果,可產出 LIST ,提供查詢結果之確認,再依此對檔案作複 (3) 可對檔案作移動,複製至別處,刪除處理,使電腦可騰出硬碟空間
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
上兩篇有關List的文章,此篇文上兩章的延續,整理一些常用的方法和操作。 [Python]List(列表)新增、修改、刪除元素 [Python基礎]容器 list(列表),tuple(元組) 還有一些常用的 list 方法和操作,讓你能更靈活地處理列表數據
Thumbnail
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
此篇文章連結 RAM 與 C語言陣列的關係並提供陣列與for-loop 使用的相關教學 前半段為基本電腦觀念、後半段為實作能力的教學
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
工具功能 (1) 彈性任意查詢檔案,如對來源目錄設定,檔案修改日期 設定,檔名特定字串或副檔名設定後,自動查出明細,並可展開至各階子目錄處理     (2) 依查詢後結果,可產出 LIST ,提供查詢結果之確認,再依此對檔案作複 (3) 可對檔案作移動,複製至別處,刪除處理,使電腦可騰出硬碟空間