py-spy について
Rustで書かれた軽量のPythonのprofiling toolsです。
プログラムがどこで重い処理をしているか関数ごとに確認できるのでパフォーマンス改善に役に立ちます。
Pythonのbuildin profilerのcProfileやprofileもありますが、プログラム全体で何%その関数が使用しているかわかりにくかったのでpy-spyを試したところ全体で何%関数が使用しているとわかりやすく出力してくれたのでありがたかったです。
Linux, Windows, Mac OS でも動作するようです。
install
- pip
- github releases page
- Homebrew
などさまざまな方法でinstallできるようです。
私はDocker内のモジュールを調べたかったので pip で入れました。
機能
py-spyでhelpを実行
py-spy --help
py-spy 0.4.0
Sampling profiler for Python programs
USAGE:
py-spy <SUBCOMMAND>
OPTIONS:
-h, --help Print help information
-V, --version Print version information
SUBCOMMANDS:
record Records stack trace information to a flamegraph, speedscope or raw file
top Displays a top like view of functions consuming CPU
dump Dumps stack traces for a target program to stdout
help Print this message or the help of the given subcommand(s)
record
プログラムの実行前に起動しprofile結果を記録してsvgなどで出力してくれる。
py-spy record -o {任意のファイル名}.svg --pid 12345
# OR
py-spy record -o {任意のファイル名}.svg -- python {something}.py
--help
py-spy-record
Records stack trace information to a flamegraph, speedscope or raw file
USAGE:
py-spy record [OPTIONS] [python_program]...
ARGS:
<python_program>... commandline of a python program to run
OPTIONS:
-p, --pid <pid> PID of a running python program to spy on
--full-filenames Show full Python filenames, instead of shortening to show only the package part
-o, --output <filename> Output filename
-f, --format <format> Output file format [default: flamegraph] [possible values: flamegraph, raw, speedscope, chrometrace]
-d, --duration <duration> The number of seconds to sample for [default: unlimited]
-r, --rate <rate> The number of samples to collect per second [default: 100]
-s, --subprocesses Profile subprocesses of the original process
-F, --function Aggregate samples by function's first line number, instead of current line number
--nolineno Do not show line numbers
-t, --threads Show thread ids in the output
-g, --gil Only include traces that are holding on to the GIL
-i, --idle Include stack traces for idle threads
--nonblocking Don't pause the python process when collecting samples. Setting this option will reduce the performance impact of sampling, but may lead to inaccurate results
-h, --help Print help information
ps aux
などで pid を調べて入力
top
リアルタイムにプログラム内で使用している関数がどの程度CPUを使用しているか出力してくれます。Unixのtopコマンドのようです。
py-spy top --pid 12345
# OR
py-spy top -- python myprogram.py
--help
py-spy-top
Displays a top like view of functions consuming CPU
USAGE:
py-spy top [OPTIONS] [python_program]...
ARGS:
<python_program>... commandline of a python program to run
OPTIONS:
-p, --pid <pid> PID of a running python program to spy on
-r, --rate <rate> The number of samples to collect per second [default: 100]
-s, --subprocesses Profile subprocesses of the original process
--full-filenames Show full Python filenames, instead of shortening to show only the package part
-g, --gil Only include traces that are holding on to the GIL
-i, --idle Include stack traces for idle threads
--delay <seconds> Delay between 'top' refreshes. [default: 1.0]
--nonblocking Don't pause the python process when collecting samples. Setting this option will reduce the performance impact of sampling, but may lead to inaccurate results
-h, --help Print help information
dump
各スレッドのコールスタックやその他の基本的なプロセス情報をコンソールに出力してくれる。
py-spy dump --pid 12345
--help
py-spy-dump
Dumps stack traces for a target program to stdout
USAGE:
py-spy dump [OPTIONS] --pid <pid>
OPTIONS:
-p, --pid <pid> PID of a running python program to spy on
--full-filenames Show full Python filenames, instead of shortening to show only the package part
-l, --locals Show local variables for each frame. Passing multiple times (-ll) increases verbosity
-j, --json Format output as JSON
-s, --subprocesses Profile subprocesses of the original process
--nonblocking Don't pause the python process when collecting samples. Setting this option will reduce the performance impact of sampling, but may lead to inaccurate results
-h, --help Print help information
Dockerでの使用
Dockerで使用する場合は
runの時に --cap-add SYS_PTRACE
compose ymal file
your_service:
cap_add:
- SYS_PTRACE
を追加する
FrameGraph
(https://github.com/brendangregg/FlameGraph)
recordの機能で出力されるfileはsvgだけでなく、[default: flamegraph] [possible values: flamegraph, raw, speedscope, chrometrace]の中から選べます。
svgで出力されるflamegraphが便利で、svgを開くとブラウザで確認できます。
上から親関数でスタック上に子関数が下に積み上がっており、深いほど処理が複雑で、横幅が多いほどCPU使用率が高いです。
関数をクリックすると全体で何%使用しているのかやズームして確認できます。
まとめ
チームでシェアする場面や、先方に報告する場面でとても重宝します。プロファイリングは初めて行いましたが、内部で意識できない関数が動作していることが可視化されて興味深かったです。
お試しください。