Pythonのtimeitモジュールで処理時間を計測

Modified: | Tags: Python, Jupyter Notebook

Pythonの標準ライブラリのtimeitモジュールを使うとコードの処理の実行時間を簡単に計測できる。

Pythonファイル内で計測する場合と、Jupyter Notebookで計測する場合について説明する。

time.time()を使ってプログラム中での経過時間を測定する方法もある。以下の記事を参照。

Pythonファイル内で計測: timeit.timeit(), timeit.repeat()

例として、連続したn個の数値の合計値を算出するシンプルな関数test(n)の処理時間を測定する。

import timeit

def test(n):
    return sum(range(n))

n = 10000
loop = 1000

result = timeit.timeit('test(n)', globals=globals(), number=loop)
print(result / loop)
# 0.0002666301020071842

timeit.timeit()関数に測定したいコードを文字列で渡すとnumber回実行され、かかった時間が返される。numberのデフォルト値は100万。時間のかかる処理を初期値のまま行うとかなり時間がかかってしまうので注意。

引数globalsglobals()を渡すことでグローバルな名前空間でコードが実行される。これがないと、上の例だと関数testや変数nが認識されない。

指定するコードは文字列ではなく呼び出し可能なオブジェクトでもいいので、引数なしのlambda式で指定できる。この場合は引数globalsは指定しなくてもよい。

result = timeit.timeit(lambda: test(n), number=loop)
print(result / loop)
# 0.00027574066299712287

結果の単位は秒。ここでは実行回数で割って1回あたりの処理時間を出力している。

割らずに実行回数を増やすと単純に結果の値も大きくなっていく。

print(timeit.timeit(lambda: test(n), number=1))
print(timeit.timeit(lambda: test(n), number=10))
print(timeit.timeit(lambda: test(n), number=100))
# 0.0003999490290880203
# 0.0038685189792886376
# 0.03517670702422038

timeit.repeat()関数を使うとtimeit()を繰り返し実行できる。結果はリストで得られる。

repeat = 5
print(timeit.repeat(lambda: test(n), repeat=repeat, number=100))
# [0.044914519996382296, 0.039663890027441084, 0.02868645201670006, 0.022745631984435022, 0.023260265996214002]

Jupyter Notebookで計測: %timeit, %%timeit

Jupyter Notebook(IPython)ではマジックコマンド%timeit, %%timeitが使える。timeitモジュールをインポートする必要はない。

以下のサンプルコードはPythonスクリプトとして実行しても計測されないので注意。Jupyter Notebookの.ipynbファイルは次のリンクから。

%timeit

%timeitでは、コマンドライン引数のようにスペースで区切って対象のコードを指定する。

デフォルトだとtimeit.timeit()におけるnumberrepeatは自動で決められる。-n-rオプションで指定することもできる。

結果は平均と標準偏差が算出される。

%timeit test(n)
# 259 µs ± 4.87 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit -r 3 -n 10000 test(n)
# 237 µs ± 6.44 µs per loop (mean ± std. dev. of 3 runs, 10000 loops each)

%%timeit

マジックコマンド%%timeitを使うとセル全体の処理時間を測定できる。

例として同じ処理をNumPyを使って実行してみる。-n-rオプションは省略可能。

セル全体の処理時間を計測するので、以下の例ではNumPyをimportする時間も含まれている。

%%timeit -r 3 -n 10000
import numpy as np
a = np.arange(n)
np.sum(a)
# 19.7 µs ± 9.57 µs per loop (mean ± std. dev. of 3 runs, 10000 loops each)

%%timeitは対象コードを引数で指定したりする必要がない。セルの先頭に%%timeitと書いておくだけなので最も簡単に使用できる。

関連カテゴリー

関連記事