⌛
Pythonで関数の時間を計測するラッパーを作成
結論
import datetime
from functools import wraps
def calc_func_time(f):
@wraps(f)
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
result = f(*args, **kwargs)
end = datetime.datetime.now()
print(f'elapsed time: {f.__name__}: { end - start }')
return result
return wrapper
@calc_func_time
def func(*args, **kwargs):
#(ある処理)
pass
内容
ある処理(func()
)の時間を計測する最も古典的な方法は以下です。
import time
def func(*args, **kwargs):
#(ある処理)
pass
start = time.time()
func()
end = time.time()
print(f'time: {func.__name__}: { end - start }')
このプログラムを毎回書くのは面倒なので関数化したいです。
例えば以下のような関数を作って実行するとします。
def calc_func_time(func, *args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'time: {func.__name__}: { end - start }')
return result
calc_func_time(func)
これでも一件落着かに思えますが、func
を呼び度にcalc_func_time
を書くのは面倒ですし、何よりmainでfunc
が実行されているか一目でわかりにくいです。
そこでfunc
に時間を計測する関数をラップしましょう。
あとプログラム完成前の余談ですが、time.time()
の結果はformatしないとユーザーフレンドリーじゃないのでdatatime.datatime.now()
を使いましょう。
以下が結論のプログラムです。
import datetime
from functools import wraps
def calc_func_time(f):
@wraps(f)
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
result = f(*args, **kwargs)
end = datetime.datetime.now()
print(f'time: {f.__name__}: { end - start }')
return result
return wrapper
@calc_func_time
def func(*args, **kwargs):
#(ある処理)
pass
func()
これでfunc()
を実行する度に時間を計測して出力してくれます。
毎回時間を計測させたくなかったら、do_print
のような引数を用意した以下のようにラッパーを実装すればいいです。
def calc_func_time(f, do_print = True):
@wraps(f)
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
result = f(*args, **kwargs)
end = datetime.datetime.now()
if do_print:
print(f'time: {f.__name__}: { end - start }')
return result
return wrapper
functools.wraps
についてはこちらで紹介しています。
Discussion