note.nkmk.me

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

Date: 2017-08-15 / tags: Python, Jupyter Notebook

Pythonの標準ライブラリのtimeitモジュールを使うとコードの処理の実行時間を簡単に計測できる。手っ取り早く調べるのに便利。

ここでは以下の2つの場合について説明する。

  • Pythonファイル内で計測: timeit
  • Jupyter Notebookで計測: %timeit, %%timeit
スポンサーリンク

Pythonファイル内で計測: timeit

連続した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式で指定してもOK。この場合は引数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モジュールをインポートする必要はない。

%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と書いておくだけなので最も簡単に使用できる。

Jupyter Notebookの例は以下のリンクにある。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事