1. 概要
line_profiler は、関数の中の各行にどのくらいの実行時間がかかっているかを計測してくれる便利ライブラリだよ(^ワ^=)
ちなみに、「引数のない関数」における line_profiler
の使い方は、以下のような記事に掲載されている。
しかし、「引数のある関数」をプロファイリングしたい時の方法が、簡単には見つからなかったので、この記事に記載しておく。
2. Environment
item | version など |
---|---|
python | 3.10 |
line_profiler | 4.1.3 |
jupyter | 1.0.0 |
3. line_profiler の使い方
まずインストールして、
$ pip install line_profiler
3-1. 引数のない関数の場合
jupyter notebook 上で、以下のように書けば動く。
ipynb
from line_profiler import LineProfiler
def main():
for i in range(0, 9999):
print(i)
return i
profiler = LineProfiler()
profiler.add_function(main)
profiler.runcall(main)
# 結果出力
profiler.print_stats()
まぁ、これはわかる。
3-2. 引数のある関数の場合
引数のある関数はどうすればいいのか、あまり明確には記事に掲載されていない。
例えばこういう関数とか。
ipynb
def main(hoge: str, huga: str):
text: str = hoge + ", " + huga + ": "
for i in range(0, 9999):
print(text, str(i))
return i
こういうのは、こうしたら動いた。
ipynb
# The sample usage of line_profiler
from line_profiler import LineProfiler
hoge: str = "なんか文字列1"
huga: str = "なんか文字列2"
profile = LineProfiler()
profile.add_function(main)
profile.runcall(main, hoge=hoge, huga=huga)
profile.print_stats()
4. 背景情報
line_profiler の以下の公式ドキュメントを読めばわかる。
runcall
関数の仕様を見て欲しい。
以下のように書かれていると思う。
def runcall(self, func, *args, **kw): """ Profile a single function call. """ self.enable_by_count() try: return func(*args, **kw) finally: self.disable_by_count()
これはつまり、 *args
や **kw
に引数を渡せるってことなんだよね。
なので、「2-2」に書いたように、今回はキーワード付き引数を渡すことにしたよ。
5. 参考
この記事にはそれっぽいことが書いてあるけれど、
例えばこんな風にしても、 profile 結果は得られなかった。
# ダメ: LineProfiler() に引数を渡した関数を渡しても、計測してくれない profile = LineProfiler(test_d(arg)) profile.print_stats()
単純に関数自体に引数を渡してしまってもダメみたい( ˘ω˘)