
原文來源 | Huy Nguyen
譯文來源 | 開源中國
雖然你所寫的每個Python程序并不總是需要嚴密的性能分析,但是當這樣的問題出現時,如果能知道Python生態系統中的許多種工具,這樣總是可以讓人安心的。
分析一個程序的性能可以歸結為回答4個基本的問題:
1.它運行的有多塊?
2.那里是速度的瓶頸?
3.它使用了多少內存?
4.哪里發生了內存泄漏?
下面,我們將用一些很酷的工具,深入細節的回答這些問題。
使用time工具粗糙定時
首先,我們可以使用快速然而粗糙的工具:古老的unix工具time,來為我們的代碼檢測運行時間。
上面三個輸入變量的意義在文章 stackoverflow article 中有詳細介紹。簡單的說:
real – 表示實際的程序運行時間
user – 表示程序在用戶態的cpu總時間
sys – 表示在內核態的cpu總時間
通過sys和user時間的求和,你可以直觀的得到系統上沒有其他程序運行時你的程序運行所需要的CPU周期。
若sys和user時間之和遠遠少于real時間,那么你可以猜測你的程序的主要性能問題很可能與IO等待相關。
使用計時上下文管理器進行細粒度計時
我們的下一個技術涉及訪問細粒度計時信息的直接代碼指令。這是一小段代碼,我發現使用專門的計時測量是非常重要的:
timer.py
為了使用它,你需要用Python的with關鍵字和Timer上下文管理器包裝想要計時的代碼塊。它將會在你的代碼塊開始執行的時候啟動計時器,在你的代碼塊結束的時候停止計時器。
這是一個使用上述代碼片段的例子:
我經常將這些計時器的輸出記錄到文件中,這樣就可以觀察我的程序的性能如何隨著時間進化。
使用分析器逐行統計時間和執行頻率
Robert Kern有一個稱作line_profiler的不錯的項目,我經常使用它查看我的腳步中每行代碼多快多頻繁的被執行。
想要使用它,你需要通過pip安裝該python包:
一旦安裝完成,你將會使用一個稱做“line_profiler”的新模組和一個“kernprof.py”可執行腳本。
想要使用該工具,首先修改你的源代碼,在想要測量的函數上裝飾@profile裝飾器。不要擔心,你不需要導入任何模組。kernprof.py腳本將會在執行的時候將它自動地注入到你的腳步的運行時。
primes.py
一旦你已經設置好了@profile裝飾器,使用kernprof.py執行你的腳步。
-l選項通知kernprof注入@profile裝飾器到你的腳步的內建函數,-v選項通知kernprof在腳本執行完畢的時候顯示計時信息。上述腳本的輸出看起來像這樣:
尋找具有高Hits值或高Time值的行。這些就是可以通過優化帶來最大改善的地方。
程序使用了多少內存?
現在我們對計時有了較好的理解,那么讓我們繼續弄清楚程序使用了多少內存。我們很幸運,Fabian Pedregosa模仿Robert Kern的line_profiler實現了一個不錯的內存分析器。
首先使用pip安裝:
(這里建議安裝psutil包,因為它可以大大改善memory_profiler的性能)。
就像line_profiler,memory_profiler也需要在感興趣的函數上面裝飾@profile裝飾器:
想要觀察你的函數使用了多少內存,像下面這樣執行:
一旦程序退出,你將會看到看起來像這樣的輸出:
line_profiler和memory_profiler的IPython快捷方式
memory_profiler和line_profiler有一個鮮為人知的小竅門,兩者都有在IPython中的快捷命令。你需要做的就是在IPython會話中輸入以下內容:
在這樣做的時候你需要訪問魔法命令%lprun和%mprun,它們的行為類似于他們的命令行形式。主要區別是你不需要使用@profiledecorator來修飾你要分析的函數。只需要在IPython會話中像先前一樣直接運行分析:
這樣可以節省你很多時間和精力,因為你的源代碼不需要為使用這些分析命令而進行修改。
內存泄漏在哪里?
cPython解釋器使用引用計數做為記錄內存使用的主要方法。這意味著每個對象包含一個計數器,當某處對該對象的引用被存儲時計數器增加,當引用被刪除時計數器遞減。當計數器到達零時,cPython解釋器就知道該對象不再被使用,所以刪除對象,釋放占用的內存。
如果程序中不再被使用的對象的引用一直被占有,那么就經常發生內存泄漏。
查找這種“內存泄漏”最快的方式是使用Marius Gedminas編寫的objgraph,這是一個極好的工具。該工具允許你查看內存中對象的數量,定位含有該對象的引用的所有代碼的位置。
一開始,首先安裝objgraph:
一旦你已經安裝了這個工具,在你的代碼中插入一行聲明調用調試器:
最普遍的對象是哪些?
在運行的時候,你可以通過執行下述指令查看程序中前20個最普遍的對象:
哪些對象已經被添加或刪除?
我們也可以查看兩個時間點之間那些對象已經被添加或刪除:
誰引用著泄漏的對象?
繼續,你還可以查看哪里包含給定對象的引用。讓我們以下述簡單的程序做為一個例子:
想要看看哪里包含變量x的引用,執行objgraph.show_backref()函數:
該命令的輸出應該是一副PNG圖像,保存在/tmp/backrefs.png,它看起來是像這樣:
在運行的時候,你可以通過執行下述指令查看程序中前20個最普遍的對象:最下面有紅字的盒子是我們感興趣的對象。我們可以看到,它被符號x引用了一次,被列表y引用了三次。如果是x引起了一個內存泄漏,我們可以使用這個方法,通過跟蹤它的所有引用,來檢查為什么它沒有自動的被釋放。
回顧一下,objgraph 使我們可以:
顯示占據python程序內存的頭N個對象
顯示一段時間以后哪些對象被刪除活增加了
在我們的腳本中顯示某個給定對象的所有引用
努力與精度
在本帖中,我給你顯示了怎樣用幾個工具來分析python程序的性能。通過這些工具與技術的武裝,你可以獲得所有需要的信息,來跟蹤一個python程序中大多數的內存泄漏,以及識別出其速度瓶頸。
對許多其他觀點來說,運行一次性能分析就意味著在努力目標與事實精度之間做出平衡。如果感到困惑,那么就實現能適應你目前需求的最簡單的解決方案。
參考
stack overflow – time explained(堆棧溢出 – 時間解釋)
line_profiler(線性分析器)
memory_profiler(內存分析器)
objgraph(對象圖)
end
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25