たとえば、ドキュメントには次のように記載されています。
ただし、timeit は、コマンドライン インターフェイスが使用されている場合にのみ、繰り返し回数を自動的に決定することに注意してください。
Pythonスクリプト内から呼び出して、繰り返し回数を自動的に決定し、最短の回数だけを返す方法はありますか?
timeit
次のようにコマンドラインから呼び出すと:
python -mtimeit -s'import test' 'test.foo()'
timeit
モジュールはスクリプトとして呼び出されます。特に、main
関数は次のように呼び出されます。
if __name__ == "__main__":
sys.exit(main())
ソースコードを見ると、main
関数がargs
引数を取ることができることがわかります:
def main(args=None):
if args is None:
args = sys.argv[1:]
実際timeit
、CLI から実行した場合とまったく同じ動作で、プログラム内から実行することができます。args
に設定するのではなく、独自のものを指定してくださいsys.argv[1:]
:
import timeit
import shlex
def foo():
total = 0
for i in range(10000):
total += i**3
return total
timeit.main(args=shlex.split("""-s'from __main__ import foo' 'foo()'"""))
のようなものを出力します
100 loops, best of 3: 7.9 msec per loop
残念ながら、main
ループごとの時間を返す代わりに、コンソールに出力します。したがって、結果をプログラムで使用したい場合、おそらく最も簡単な方法は、main
関数をコピーしてから変更することです。代わりに、印刷コードを return に変更しますusec
。
OPによる例:
これを次の場所に配置するとutils_timeit.py
:
import timeit
def timeit_auto(stmt="pass", setup="pass", repeat=3):
"""
http://stackoverflow.com/q/19062202/190597 (endolith)
Imitate default behavior when timeit is run as a script.
Runs enough loops so that total execution time is greater than 0.2 sec,
and then repeats that 3 times and keeps the lowest value.
Returns the number of loops and the time for each loop in microseconds
"""
t = timeit.Timer(stmt, setup)
# determine number so that 0.2 <= total time < 2.0
for i in range(1, 10):
number = 10**i
x = t.timeit(number) # seconds
if x >= 0.2:
break
r = t.repeat(repeat, number)
best = min(r)
usec = best * 1e6 / number
return number, usec
次のようなスクリプトで使用できます。
import timeit
import utils_timeit as UT
def foo():
total = 0
for i in range(10000):
total += i**3
return total
num, timing = UT.timeit_auto(setup='from __main__ import foo', stmt='foo()')
print(num, timing)
Python 3.6 の時点で、timeit.Timer
オブジェクトには、コマンド ライン実行で がautorange
どのように決定されるかを公開する関数があります。number