目錄

廣告 AD

py-spy: 找出 Python 程式性能瓶頸

最近覺得這個套件蠻好用的

所以就整理一下做個紀錄

廣告 AD

Github - py-spy

py-spy 是一款用 Rust 寫的 Python Sampling Profiler,使用上完全不需要修改 Python source code,且執行時會是執行在另外的 Process 上,對於 Profiling 來說,Overhead 是很低的。目前,py-spy 支援在 Linux, OSX, Windows 和 FreeBSD 上使用,CPython 版本支援 Python2 (2.3-2.7) 和 Python3 (3.3-3.13)


最簡單的方式直接用 pip 安裝就 OK 了

shell

pip install py-spy

也可以到 Github Release 上下載編譯好的版本 Link


py-spy 一共有三個功能,接下來我們就來好好分別介紹:

  • Record
  • Top
  • Dump

Record 會記錄每個 function 所花費的時間,並製作成 flame graph,然後輸出到 svg 檔案。

shell

py-spy record [-o <svg_file>] -- python3 <script>
py-spy record [-o <svg_file>] --pid <pid>

範例:

shell

py-spy record -- python3 chart.py

record


Top 可以看到程式在運行的過程中在甚麼地方花費比較多的時間,可以更好的找出效能瓶頸的地方。

shell

py-spy top -- python3 <script>
py-spy top --pid <pid>

範例:

shell

py-spy top -- python3 chart.py

top


Dump 可以看到當前程式運行的 call stack,如果程式卡住了,或是想知道當前運行的階段,都是很好用的工具。

shell

py-spy dump --pid <pid>

範例:

shell

python3 -m http.server &
py-spy dump --pid $!

dump


由於 py-spy 是運行在另一個 Process 上,如果要讀取其他 Process 的記憶體需要有 root 權限,因此我們需要使用 root 權限運行,如果不使用 root 權限的話會出現下面的錯誤:

shell

Permission Denied: Try running again with elevated permissions by going 'sudo env "PATH=$PATH" !!'

如果單純加上 sudo 運行,則會找不到 py-spy:

shell

sudo: py-spy: command not found

因為為了安全因素,sudo 並不會直接讀取目前使用者的 PATH 環境變數,自然找不到 py-spy,且 sudo -E 也並不會讀取 PATHPYTHONPATH,所以也不能用,最終的解法就是如訊息所示,前面加上:

shell

sudo env "PATH=$PATH"

例如:

shell

sudo env "PATH=$PATH" py-spy dump --pid 1111
Note
!! 在 bash 中代表上次執行的指令

如果說你用到的 Python 套件是安裝在使用者的 home,那要另外設定 PYTHONPATH,不然 root 會找不到套件

shell

sudo env "PATH=$PATH" "PYTHONPATH=<path>"

例如:

shell

sudo env "PATH=$PATH" "PYTHONPATH=/home/ubuntu/.local/lib/python3.10/site-packages" py-spy top --pid 1111


廣告 AD