Pythonで計算処理時間を計測する方法

Pythonで計算処理時間を計測する最強ガイド
【Qiita投稿の改訂版】

この記事は、筆者が昔 Qiita に投稿していた内容を大幅にブラッシュアップした完全版です。
「処理が遅い…どこがボトルネック?」
「Pythonで正しい計測ってどうやるの?」
そんな悩みを一気に解決する “決定版ガイド” を目指してまとめ直しました。

単純に time.time() を使うだけでは正確な計測にならないケースも多く、
用途に応じて perf_counter などを使い分ける必要があります。

この記事では、初心者~中級者がすぐに使えるよう、
「どれをいつ使えばいいのか?」
まで分かりやすく整理しています。

目次

  1. モジュールを使わない時間計測(%%time / %%timeit)
  2. timeモジュールを使う時間計測
    2-1. time.time()
    2-2. time.perf_counter()
    2-3. time.process_time()
    2-4. time.monotonic()
  3. 実際に計測してみる(フィボナッチ)
  4. まとめ

1. モジュールを使わない計測方法(Jupyter専用)

Jupyter Notebook では、マジックコマンド %%time%%timeit が使えます。

%%time
# 処理
%%timeit
# 処理

ただし、ブロックの先頭にしか書けないため、部分的な処理の計測には不向きです。


2. timeモジュールを使う計測方法

Pythonの標準ライブラリ time を使うと、任意の処理を挟んで計測ができます。

2-1. time.time()

import time

start = time.time()
# 処理
end = time.time()

print(end - start)

2-2. time.perf_counter()(最も推奨)

import time

start = time.perf_counter()
# 処理
end = time.perf_counter()

print(end - start)

高分解能タイマーで最も精度が高く、基本はこれを使えばOK。

2-3. time.process_time()

import time

start = time.process_time()
# 処理
end = time.process_time()

print(end - start)

CPU時間だけを計測するので sleep() の影響を受けません。

2-4. time.monotonic()

import time

start = time.monotonic()
# 処理
end = time.monotonic()

print(end - start)

後戻りしない時刻を返すので、経過時間計測に向いています。


3. 実際に計測してみる(フィボナッチ)

次のような再帰フィボナッチで測定します。

def fibonacci(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fibonacci(n - 1) + fibonacci(n - 2)

Jupyter の %%time を使うと以下のようになります。

%%time
fibonacci(30)
# Wall time: 271 ms

%%timeit は複数回の平均を計測します。

%%timeit
fibonacci(30)
# 309 ms ± 13.2 ms per loop

色んな情報(誤差・実行回数など)が出力されますが、309ms の部分が計測時間になります。

timeモジュールを使った4種類の計測を一気に比較(5回平均)

以下では、time.time / perf_counter / process_time / monotonic の4種類を使い、
それぞれ5回計測した平均時間を比較します。

import time

def cal_time(x):
    if x == 0:
        return time.time()
    if x == 1:
        return time.perf_counter()
    if x == 2:
        return time.process_time()
    if x == 3:
        return time.monotonic()

n = 5
time_list = ["time.time", "time.perf_counter", "time.process_time", "time.monotonic"]

for j in range(4):
    t = 0
    for i in range(n):
        start = cal_time(j)
        fibonacci(30)
        end = cal_time(j)
        t += end - start
    print(time_list[j], ":{0:.10f}".format(t / 5))

■ 出力結果

計測方法 平均処理時間(秒)
time.time() 0.2656502724
time.perf_counter() 0.2656119600
time.process_time() 0.2718750000
time.monotonic() 0.2812000000


4. まとめ

  • 正確な計測 → time.perf_counter() を使うのがベスト
  • Jupyterなら %%timeit が簡単かつ正確
  • CPU時間だけ測る → process_time()
  • 戻らない時刻が欲しい → monotonic()

基本的に time.perf_counter() を使っておけば間違いありません。 Windows の QueryPerformanceCounter に匹敵する高分解能タイマーで、 timeit でも内部的に使用されています。

ぜひ用途に応じて、最適な計測方法を使い分けてみてください!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA