Pythonのwith
ブロックの実行時間を測るユーティリティクラスStopwatch
を書いた。
複数のパラメータ・方式での実行速度を比較したい場合、計測結果をプログラム的にシームレスに取得してグラフ描画処理へと続けていきたくなる。Python でコード片の実行速度を測るなら、timeit
を使うのが一般的だろう。しかし、どうにも timeit
で計測結果をプログラム的に取得する方法が分からなかった。なので車輪の再発明をしてみた次第。
モノとしては単純で、Stopwatch
オブジェクトをwith
文にて使用すると with
ブロックの開始と終了の時間を測って内部的に記録する。実行時間は何度も計測することができ、mean()
でそれらの平均、stdev()
で標準偏差を計算する。またstr()
で文字列にするとtimeitっぽい形式で実行時間を表示するので、たとえば print()
に渡せば結果を表示できる。実行例をいくつか:
>>> sw = Stopwatch() >>> for _ in range(2): ... with sw: ... sum(n for n in range(1_000_000)) >>> print(sw) 64.4 ms ± 5.05 ms per laps (mean ± std. dev. of 2 laps) >>> sw.mean('ms'), sw.stdev('ms') (64.3803169889452, 5.054087780470232)
また、Stopwatch
オブジェクトの生成時に print
関数や logging.debug
関数を渡してやると、with
ブロックを抜けるたびにその関数で実行時間を表示する:
>>> sw = Stopwatch(print) >>> for _ in range(2): ... with sw: ... sum(n for n in range(1_000_000)) 73.8 ms ± nan ms per laps (mean ± std. dev. of 1 laps) 67.4 ms ± 8.97 ms per laps (mean ± std. dev. of 2 laps)
実装コードは Gist として、GitHub で公開中。