[Python]使用tracemalloc 模組來比較兩種不同方法所佔用的記憶體大小

閱讀時間約 1 分鐘

透過 Python 的 tracemalloc 模組來比較兩種方法在執行過程中佔用的記憶體大小。以下是兩者的記憶體佔用比較範例。

程式說明

  • tracemalloc.start():開始追踪記憶體分配。
  • tracemalloc.get_traced_memory():返回當前和峰值的記憶體使用量(以byte為單位)。
  • tracemalloc.stop():停止追踪記憶體。

預期結果

  • 儲存路徑後再讀取:因為所有影像路徑會被儲存到列表中,所以當前和峰值記憶體使用量會比較大。
  • 使用 yield:因為路徑是逐步生成的,不會一次性佔用大塊記憶體,所以記憶體使用量應該會較低。

Python版本

3.11.3

1. 儲存路徑後再讀取的方式

import os
import tracemalloc

def get_image_paths(directory):
image_paths = []
for filename in os.listdir(directory):
if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp')):
image_paths.append(os.path.join(directory, filename))
return image_paths

directory_path = '/path/to/your/images'

# 開始追踪記憶體
tracemalloc.start()

# 執行儲存路徑後再讀取的方法
image_paths = get_image_paths(directory_path)

for _ in image_paths:
pass

# 獲取記憶體使用情況
current, peak = tracemalloc.get_traced_memory()
print(f"儲存路徑後再讀取方法 - 當前記憶體使用: {current / 10**6:.2f} MB; 峰值記憶體使用: {peak / 10**6:.2f} MB")

# 停止追踪記憶體
tracemalloc.stop()

2. 使用 yield 生成器的方式

import os
import tracemalloc

def process_images_in_directory(directory):
for filename in os.listdir(directory):
if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp')):
img_path = os.path.join(directory, filename)
yield img_path

directory_path = '/path/to/your/images'

# 開始追踪記憶體
tracemalloc.start()

# 執行使用 yield 的方法
for _ in process_images_in_directory(directory_path):
pass

# 獲取記憶體使用情況
current, peak = tracemalloc.get_traced_memory()
print(f"使用 yield 方法 - 當前記憶體使用: {current :.6f} B; 峰值記憶體使用: {peak / 10**3:.2f} KB")

# 停止追踪記憶體
tracemalloc.stop()



raw-image
  • 結果是使用yield生成的方式,占用的記憶體比較高:

可能原因:

  • 生成器狀態的管理:生成器在每次 yield 時會保存其執行狀態,這包括當前執行的位置、局部變量等。這些額外的開銷可能會比一次性儲存所有路徑的內存開銷略高,即使整體記憶體佔用量非常小。
  • 記憶體分配和釋放:生成器函數的內存分配和釋放模式可能會導致記憶體使用的峰值略高。即使每次 yield 不會大量使用記憶體,但管理生成器狀態的開銷可能使得峰值記憶體使用稍高。

怎麼會跟課本上教的不一樣呢??

這次我們用讀取文件的方式來測試,讀取含有2864433的文件檔(一推無意義的數字)

raw-image
import tracemalloc
def read_entire_file(filename):
with open(filename, 'r') as file:
content = file.read()
return content

def read_file_line_by_line(filename):
with open(filename, 'r') as file:
for line in file:
yield line

# 執行一次性讀取整個文件的方法
tracemalloc.start()
file_content = read_entire_file('D:\sss.txt')
for _ in file_content:
pass
current, peak = tracemalloc.get_traced_memory()
print(f"一次性讀取整個文件 - 當前記憶體使用: {current:.6f} B; 峰值記憶體使用: {peak / 10**3:.2f} KB")
tracemalloc.stop()

# 執行yield的方法
tracemalloc.start()
for line in read_file_line_by_line('D:\sss.txt'):
pass
current, peak = tracemalloc.get_traced_memory()
print(f"逐行讀取文件使用 yield - 當前記憶體使用: {current:.6f} B; 峰值記憶體使用: {peak / 10**3:.2f} KB")
tracemalloc.stop()
raw-image

這次yield使用的記憶體明顯就比較小了。

使用 yield 主要優勢在於對於大型文件或數據流的記憶體效率。即使每次 yield 帶來一定的性能開銷,但記憶體使用上的節省是明顯看的到的。




113會員
172內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
留言0
查看全部
發表第一個留言支持創作者!
螃蟹_crab的沙龍 的其他內容
現在有一推AI網站提供模糊圖片變高清的工具,Google關鍵字一下就一推了,例如MyEdit,Artguru等等。 Python的OpenCV有提供一個DnnSuperResImpl Class Reference,也可以做到這件事,就讓我們繼續往下看吧。 在OpenCV DnnSuperRe
現在的圖片都蠻大張的,若整張丟下去做AVI檢測,相對的時間會要比較久一點,事先擷取出感興趣的區域來檢測,就會縮短整個測試的時間。 本文主要提供一個擷取ROI的函式。 從圖片中裁剪出指定的感興趣區域(ROI)。 def crop_img(img, x, y, h, w): """
本文延續上兩篇文章,新增印出圖像中OCR的面積及位置,與驗證連通域分析計算的面積是否正確,利用cv2.countNonZero來計算區域內非零的元素,因圖像OCR在連通域分析前就需轉換成黑底白字,剛好可利用此函數來計算面積。 [OpenCV][Python]印出圖像中文字的位置及高寬 結果圖
在tesseract-ocr辨識應用中,建議的留白邊框為10pixl,若Label列印的太剛好,沒有任何的邊框時,就會辨識不到文字。 本文將帶大家如何讓圖像增加邊框。 結果圖 示意的比較誇張,我讓邊框增加100pixl,圖片大小原為211*80。
本文將說明如何去辨識出圖片文字​位置及高寬。
現在有一推AI網站提供模糊圖片變高清的工具,Google關鍵字一下就一推了,例如MyEdit,Artguru等等。 Python的OpenCV有提供一個DnnSuperResImpl Class Reference,也可以做到這件事,就讓我們繼續往下看吧。 在OpenCV DnnSuperRe
現在的圖片都蠻大張的,若整張丟下去做AVI檢測,相對的時間會要比較久一點,事先擷取出感興趣的區域來檢測,就會縮短整個測試的時間。 本文主要提供一個擷取ROI的函式。 從圖片中裁剪出指定的感興趣區域(ROI)。 def crop_img(img, x, y, h, w): """
本文延續上兩篇文章,新增印出圖像中OCR的面積及位置,與驗證連通域分析計算的面積是否正確,利用cv2.countNonZero來計算區域內非零的元素,因圖像OCR在連通域分析前就需轉換成黑底白字,剛好可利用此函數來計算面積。 [OpenCV][Python]印出圖像中文字的位置及高寬 結果圖
在tesseract-ocr辨識應用中,建議的留白邊框為10pixl,若Label列印的太剛好,沒有任何的邊框時,就會辨識不到文字。 本文將帶大家如何讓圖像增加邊框。 結果圖 示意的比較誇張,我讓邊框增加100pixl,圖片大小原為211*80。
本文將說明如何去辨識出圖片文字​位置及高寬。
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
上兩篇有關List的文章,此篇文上兩章的延續,整理一些常用的方法和操作。 [Python]List(列表)新增、修改、刪除元素 [Python基礎]容器 list(列表),tuple(元組) 還有一些常用的 list 方法和操作,讓你能更靈活地處理列表數據
Thumbnail
在 Python 中,print( ) 函數用於將結果輸出到螢幕上。當你嘗試將不同資料型別(例如字串和數字)混合在一起輸出時,print( )函數無法直接處理這些不同型別的資料,因此你需要先將它們轉換為相同的資料型別。通常,這意味著需要將數字轉換為字串型別,以便與其他字串一同輸出。 雖然我們也可以
Thumbnail
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
此篇文章連結 RAM 與 C語言陣列的關係並提供陣列與for-loop 使用的相關教學 前半段為基本電腦觀念、後半段為實作能力的教學
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
Lua 開檔寫檔的運用 io.output()...
Thumbnail
在 Python 中,dir() 函式用於列舉對象的所有屬性和方法。這包括對象的內建屬性、方法以及自定義的屬性和方法。以下是一個簡單的示例: 列舉所有屬性與方法 class MyClass: def __init__(self): self.attribute1 = 42
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
上兩篇有關List的文章,此篇文上兩章的延續,整理一些常用的方法和操作。 [Python]List(列表)新增、修改、刪除元素 [Python基礎]容器 list(列表),tuple(元組) 還有一些常用的 list 方法和操作,讓你能更靈活地處理列表數據
Thumbnail
在 Python 中,print( ) 函數用於將結果輸出到螢幕上。當你嘗試將不同資料型別(例如字串和數字)混合在一起輸出時,print( )函數無法直接處理這些不同型別的資料,因此你需要先將它們轉換為相同的資料型別。通常,這意味著需要將數字轉換為字串型別,以便與其他字串一同輸出。 雖然我們也可以
Thumbnail
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
此篇文章連結 RAM 與 C語言陣列的關係並提供陣列與for-loop 使用的相關教學 前半段為基本電腦觀念、後半段為實作能力的教學
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
Lua 開檔寫檔的運用 io.output()...
Thumbnail
在 Python 中,dir() 函式用於列舉對象的所有屬性和方法。這包括對象的內建屬性、方法以及自定義的屬性和方法。以下是一個簡單的示例: 列舉所有屬性與方法 class MyClass: def __init__(self): self.attribute1 = 42