LoginSignup
1

More than 5 years have passed since last update.

line_profiler with multiprocessing

Last updated at Posted at 2018-12-18

はじめに

pythonの処理時間計測ツールの定番、line_profilerだけど、マルチプロセスなプログラムで動かすのにちょい苦労したのでメモ。

どれどれ

そもそも公式ドキュメントって
https://github.com/rkern/line_profiler の下の方にあるのくらいだよね? 不親切!

で、

from multiprocessing import Process

def child(num):
    ...

def main():
    for i in range(5):
        p = Process(target=child, args=(i,))
        p.start()

みたいなプログラムでボトルネックを探そうと思ってcProfileやline_profilerを使うわけだが、

from multiprocessing import Process

@profile
def child(num):
    ...

@proile
def main():
    for i in range(5):
        p = Process(target=child, args=(i,))
        p.start()

なんてやってもchildの中までは計測してくれないのよね。普通の関数ならもちろんいけるよ? でも別プロセスにしちゃうとダメっぽい。cProfileも同様。で、いろいろググったり公式ドキュメント見たりしながらもサクっと正解は転がっておらず試行錯誤。(stackOverflowのQAがとても参考に)

お願い、できて

結論、子プロセスに wrap をかませることにより成功。

from multiprocessing import Process
from line_profiler import LineProfiler

def child(num):
    ...

def wrap(num):
    prof = LineProfiler()
    prof.add_function(child)
    prof.runcall(child, num)
    prof.print_stats()
    prof.dump_stats('xxx%d.prof'%num)

def main():
    for i in range(5):
        p = Process(target=wrap, args=(i,))
        p.start()

dump でファイル名をプロセスごとに分けてあげないと最後に終了したので上書きされてしまう模様。

おわりに

もっといい方法がありそう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1