🐥

Pythonの実行速度を測定(プロファイル)

2022/05/25に公開

※python3.7での実行結果です。

測定したい処理を関数で定義しておいてデコレータをつけるだけで測定できる方法を紹介します。

ライブラリ(pstats,cProfile)の活用

pythonの標準ライブラリに含まれるpstats,cProfileを使用して測定してプロファイルを出力してみましょう。

デコレータを定義する関数(定義しておく)
import pstats
import cProfile

def execution_speed_lib(func):
    """
    実行速度計測用のデコレータ
    """
    def wrapper(*args, **kwargs):
        pr = cProfile.Profile()
        # 実行処理の計測
        pr.runcall(func, *args, **kwargs)

        stats = pstats.Stats(pr)
        stats.print_stats()
    return wrapper

デコレータが作成できたので、これを利用して測定してみましょう。
測定をしたい関数にデコレータを付けます。

test.py
@execution_speed_lib
def test():
    s = 0
    for i in range(100000000):
        s = s + 1

test()
実行結果
         2 function calls in 5.023 seconds

   Random listing order was used

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    5.023    5.023    5.023    5.023 test.py:35(test)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

ncalls その処理が何回呼び出されたか
tottime 与えられた関数に消費された合計時間
percall 一回呼び出しあたりの消費された合計時間

5秒近くかかったことがわかりました。

timeライブラリを使用する

デコレータを定義する関数(定義しておく)
def execution_speed(func):
    """
    実行速度計測用のデコレータ
    """
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print("実行時間" + str(run_time) + "秒")
    return wrapper

では測定してみましょう。

test.py
@execution_speed
def test():
    s = 0
    for i in range(100000000):
        s = s + 1

test()
実行結果
実行時間5.148618300000001秒

まとめ

cProfileを使用することで実行時間だけでなく,呼び出し回数なども測定が可能!!
逆に実行時間だけを測定したい場合はtimeだけで十分といえる。

Discussion