contextmanager
を使ってwith
ブロック内の処理を複数回実行し平均の速度を計る機能を考えています。
JupyterNotebooksなどのIPython系での%%timeit
の簡易版と思っていただければと思います。
下記のコードを書いてみたのですが、AttributeError: __enter__
が出てしまいます。
contextmanager_timer()
の部分をreturn contextmanager_timer()
とするとエラーは出ないのですが、1度しか実行されないためにコードの意味がなくなります。
どう書き換えればよいでしょうか?
また、計測する処理にprint()
などが含まれていた場合os.devnull
に流して静かに実行することも考えているのですが、そちらについてもアドバイスがあれば伺いたいです。
Python
1import time 2from contextlib import contextmanager 3 4 5def simple_timeit(label: str, exec_limit: int = 1000, time_limit: int = 5): 6 @contextmanager 7 def contextmanager_timer(): 8 start = time.time() 9 yield 10 nonlocal total_time 11 total_time += time.time() - start 12 13 cnt = 0 14 total_time = 0 15 while cnt < exec_limit and total_time < time_limit: 16 cnt += 1 17 contextmanager_timer() 18 print(f"{label}: {total_time / cnt:.8f}s on average of {cnt} runs.") 19 20 21def main(): 22 with simple_timeit("for loops"): 23 for _ in range(10 ** 7): 24 pass 25 26 27if __name__ == "__main__": 28 main() 29
error
1for loops: 0.00000000s on average of 1000 runs. 2Traceback (most recent call last): 3 File "prog.py", line 28, in <module> 4 main() 5 File "prog.py", line 22, in main 6 with simple_timeit("for loops"): 7AttributeError: __enter__
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/07/12 01:59