たそらぼ

日頃思ったこととかメモとか。

timeitモジュールで呼び出し可能オブジェクトの時間を計測する。

tensorflowのドキュメントを見てたら、timeitというモジュールを使っていたので、これなんやねんと思って調べた。

docs.python.org

Pythonからtimeitをimportして使う場合は、式を文字列として渡すか、呼び出し可能な式あれば時間を計測することができる。

例1

import timeit

timeit.timeit(lambda: print(1), number=10)
1
1
1
1
1
1
1
1
1
1
0.0006752069998583465

例2

import timeit

def test(i):
  for i in range(i):
      print("aaa")

timeit.timeit(lambda: test(1), number=10)
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
0.0003541580000501199

例3

import timeit

timeit.timeit("print(1)", number= 10)
1
1
1
1
1
1
1
1
1
1
0.00039979700000003504

なお、文字列を渡す例3のような場合は、以下のように文字列の外側で定義した関数だとダメだった。難しい。

例4(NG)

import timeit

def test(i):
  for i in range(i):
      print("aaa")

timeit.timeit("test(10)", number= 10)
NameError                                 Traceback (most recent call last)
<ipython-input-8-e602a5cee3d7> in <module>()
----> 1 timeit.timeit("test(10)", number= 10)

/usr/lib/python3.7/timeit.py in timeit(stmt, setup, timer, number, globals)
    231            number=default_number, globals=None):
    232     """Convenience function to create Timer object and call timeit method."""
--> 233     return Timer(stmt, setup, timer, globals).timeit(number)
    234 
    235 def repeat(stmt="pass", setup="pass", timer=default_timer,

/usr/lib/python3.7/timeit.py in timeit(self, number)
    175         gc.disable()
    176         try:
--> 177             timing = self.inner(it, self.timer)
    178         finally:
    179             if gcold:

/usr/lib/python3.7/timeit.py in inner(_it, _timer)

NameError: name 'test' is not defined

ちなみに文字列で無理やり食わせると動いた。

例4(OK)

import timeit

formula_str = """
def test(i):
  for i in range(i):
      print('aaa')
test(10)"""

timeit.timeit(formula_str, number= 1)
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
0.0010455369999817776

SQLのクエリ書いたり、PyStanのコード書いたりするときは文字列でよく渡すけど、標準ライブラリで求められることがなかったので、新鮮な体験だった。