プログラミング/python の変更点

更新


#author("2026-01-06T12:57:54+00:00","default:administrator","administrator")
#author("2026-01-06T12:58:13+00:00","default:administrator","administrator")
[[公開メモ]]

* プロファイリング [#t0ad56a0]

python は普通に書くと思った以上に遅いことになる場合が多いので、
プロファイリングの結果を基に重い処理を numpy 側に移したりするのが役に立つ

いろいろ試した結果、特に並列処理を使ったバッチ処理が走るライブラリを使う場合には
jupyter 上でのプロファイリングするとライブラリ関数の実行中に UI スレッドが動いて
プロファイル結果が無茶苦茶になるようです。

したがって面倒でもプロファイルは Jupyter 外で行った方が間違いない。

** 前処理結果を dump する [#j33e19a7]

jupyter 上で計算した結果を引き継ぎつつ
jupyter 外で処理を回すには、前処理で得られたデータ(プロファイリングしたい処理への入力)を
pickle.dump しておき、外部で動かす処理ではそれを呼んで動作を行う

Jupyter セル内で実行
 LANG:python
 import pickle
 payload = {
     "param1": param1,
     "param2": param2,
     "param3": param3,
 }
 with open("payload.pkl", "wb") as f:
     pickle.dump(payload, f, protocol=pickle.HIGHEST?PROTOCOL)

で(通常の python データであれば)書き出せる

** 読み込んで動かす .py ファイル [#gd0caee2]

do_profile.py
 LANG:python
 import pickle
 import cProfile
 import pstats
 
 from my_module import func_to_profile
 
 def main():
     with open("payload.pkl", "rb") as f:
         payload = pickle.load(f)
 
     prof = cProfile.Profile()
     prof.enable()
     refined = func_to_profile(**payload)
     prof.disable()
 
     prof.dump_stats("prof.out")
 
 if __name__ == "__main__":
     main()

** 実行する [#d467ea3d]

 LANG:console
 $ python do_profile.py

** 解析する [#s2942399]

 LANG:console
 $ python -m pstats prof.out
 Welcome to the profile statistics browser.
 prof.out% strip        # strip directory names
 prof.out% sort cumtime # sort by cumtime
 prof.out% stats 40     # show first 40 items

これで、

my_module.py:1234(my_function)

みたいな関数ごとに

 LANG:console
 ncalls   tottime  percall  cumtime  percall filename:lineno(function)
 呼び出し 自前処理 呼び出し 子も含む 呼び出し ファイル名:行番号(関数名)
 回数     時間     あたり   全時間   あたり

のリストが出ます

特定の関数内から呼ばれている分だけを調べたければ、

  LANG:console
  prof.out% sort time
  prof.out% callees my_module.py:1234(my_function)
 LANG:console
 prof.out% sort time
 prof.out% callees my_module.py:1234(my_function)

などとします。

Counter: 117 (from 2010/06/03), today: 2, yesterday: 16