2008年10月7日火曜日

Python でメソッドの実行時間の計測

1. timeit モジュールでコードの実行時間を計測する

Python で大雑把にコードの実行時間を知りたい場合、datatime オブジェクトを利用する。

Python のコードを実行するとき、バックグラウンドで実行されているプロセスがある。正確なメソッドの実行時間を測定するには、datetime はなく、timeit モジュール を使う必要がある。

18.2. Using the timeit Module によると、

Before you start your timing tests, turn everything off and disconnect from the network. Then turn off all the things you forgot to turn off the first time, then turn off the service that's incessantly checking whether the network has come back yet, then ...

… Don't write your own timing framework. Python 2.3 comes with a perfectly good one called timeit.

26.6. timeit — 小さなコード断片の実行時間計測 — Python 2.7ja1 documentation

このモジュールは Python の小さなコード断片の時間を簡単に計測する手段を提供します。インターフェースはコマンドラインとメソッドとして呼び出し可能なものの両方を備えています。また、このモジュールは実行時間の計測にあたり陥りがちな落し穴に対する様々な対策が取られています。

デフォルトでは、 timeit() は時間計測中、一時的にガーベッジコレクション(garbage collection)を切ります。このアプローチの利点は、個別の測定結果を比較しやすくなることです。不利な点は、GC が測定している関数のパフォーマンスの重要な一部かもしれないということです。

 

2. timeit モジュールの使い方

例えば、hoge モジュールに add 関数があるとする。

hoge.py

def add(x,y):
    return x + y

時間を計測をするために、モジュール timeittest を作成したら、

  1. timeit モジュールを import
  2. Timer クラスオブジェクトを生成。その際、引数の
    • 2 引数に、テストしたいモジュールを import する文を文字列として渡す
    • 1 引数に、テストしたい関数の呼出しを文字列として渡す

timeittest.py

import timeit
# hoge モジュールをインポートして、hoge.add() をテスト対象とする
t = timeit.Timer("hoge.add(100,200)", "import hoge")

# デフォルトで100 万回繰り返される
print t.timeit()

結果は、

0.704536470417

 

メソッドを繰り返す回数を指定する

実行したい回数を指定したい場合は、timeit メソッドに数値を指定する。

# 1000 回繰り返す
print t.timeit(1000)

 

テストを繰り返す回数を指定する

# テストを 3 回繰り返す
print t.repeat(3)

結果は、

[0.71494449713588892, 0.69049809403145446, 0.68933928753517648]

メソッドの実行回数も指定したい場合は、

print t.repeat(3, 1000)

結果は、

[0.0012822858770960011, 0.00075568263571312855, 0.00067829849876943626]

10.10 timeit -- 小さなコード断片の実行時間計測 の repeat() の注意事項には、次のように書かれている。、

多くの場合、最も低い値がそのマシンが与えられたコード断片を実行する場合の下限値です。結果のうち高めの値は、Python のスピードが一定しないために生じたものではなく、時刻取得の際他のプロセスと衝突がおこったため、正確さが損なわれた結果生じたもの です。したがって、結果のうち min() だけが見るべき値となります。

ということで、

print min(t.repeat(3))