Pythonで計算処理時間を計測する最強ガイド
【Qiita投稿の改訂版】
この記事は、筆者が昔 Qiita に投稿していた内容を大幅にブラッシュアップした完全版です。
「処理が遅い…どこがボトルネック?」
「Pythonで正しい計測ってどうやるの?」
そんな悩みを一気に解決する “決定版ガイド” を目指してまとめ直しました。
単純に time.time() を使うだけでは正確な計測にならないケースも多く、
用途に応じて perf_counter などを使い分ける必要があります。
この記事では、初心者~中級者がすぐに使えるよう、
「どれをいつ使えばいいのか?」
まで分かりやすく整理しています。
目次
- モジュールを使わない時間計測(%%time / %%timeit)
- timeモジュールを使う時間計測
2-1. time.time()
2-2. time.perf_counter()
2-3. time.process_time()
2-4. time.monotonic() - 実際に計測してみる(フィボナッチ)
- まとめ
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 でも内部的に使用されています。
ぜひ用途に応じて、最適な計測方法を使い分けてみてください!