pythonのデコレータを使ってお手軽ベンチマーク
pythonにはデコレータというよく分からないものがありまして。 よく分からないので込み入った解説はしないけれど、ともかく関数をデコレーションするもののようです。
使い方は簡単 ・・・かは分からないけれど、まあそれなりに。
import time import functools def Timer(func): @functools.wraps(func) def Wrapper(*args, **kw): stime = time.clock() ret = func(*args, **kw) etime = time.clock() print '{0}: {1:,f}ms'.format(func.__name__, (etime-stime)*1000) return ret return Wrapper @Timer def Test(): print 'hello, decorator' Test()
こんな感じで使うと、Test関数の実行時間を測ってくれます。計測対象はいくつでもおっけー。
計りたい関数の上に一行付け足すだけだから、お手軽でいいよね。 ミリ秒単位で測ってる割に関数のオーバーヘッドを考慮してないから、あんまよろしくないですが。
デコレーターに引数を付けたい時は
import time import functools def Timer(name): def Deco(func): @functools.wraps(func) def Wrapper(*args, **kw): stime = time.clock() ret = func(*args, **kw) etime = time.clock() print '{0}: {1:,f}ms'.format(name, (etime-stime)*1000) return ret return Wrapper return Deco @Timer('decorator test') def Test(): print 'hello, decorator' Test()
なんてやればおっけー。 三重のdefとかあんまり使いたくないけどね・・・見づらい・・・。
ちなみに、内部的には
def Deco(func): def Wrapper(*args, **kw): print func.__name__ return func(*args, **kw) return Wrapper def Test(): print 'a' Test = Deco(Test)
ってやるのと同義みたいね。
引数付きの場合は
Test = Deco(u'引数')(Test)
ということになるみたい。
じゃあ@functools.wraps(func)
は何かって? それが分からんのだよ。
省略すると、複数の関数をデコレーションした時におかしくなるんだけどね。後はよく分からん。