我写了一个通用框架,帮助我对代码关键部分进行基准测试。
以下是对框架的解释,最后是我面临的问题以及我对解决方案的一些想法。
基本上,我正在寻找更优雅的解决方案
假设我有一个执行此操作的函数(伪代码):
#Pseudo Code - Don't expect it to run
def foo():
do_begin()
do_critical()
some_value = do_end()
return some_value
我想在循环中多次运行“do_critical”部分并测量时间但仍然得到返回值。
所以,我写了BenchMarker类,它的api是这样的:
#Pseudo Code - Don't expect it to run
bm = BenchMarker(first=do_begin, critical=do_critical, end=do_end)
bm.start_benchmarking()
returned_value = bm.returned_value
benchmark_result = bm.time
本Benckmarker内部执行以下操作:
#Pseudo Code - Don't expect it to run
class BenchMarker:
def __init__(self):
.....
def start_benchmarking(self):
first()
t0 = take_time
for i in range(n_loops):
critical()
t1 = take_time
self.time = (t1-t0)/n_loops
value = end()
self.returned_value = value
重要的是要提到我也能够在第一个,关键函数和结束函数之间传递上下文,但为了简单起见我省略了它,因为这不是我问题的要点。
在以下用例之前,此框架就像魅力一样:
我有以下代码
#Pseudo Code - Don't expect it to run
def bar():
do_begin()
with some_context_manager() as ctx:
do_critical()
some_value = do_end()
return some_value
现在,经过这个漫长的介绍(对不起......),我正在回答真正的问题。
我不想在时间测量循环中运行“with statement”,但关键代码需要上下文管理器。
所以我基本上想要的就是以下分解吧:
first -> do_begin() + "what happens in the with before the with body"
critical -> do_critical()
end -> "what happens after the with body" + do_end()
我想到的两个解决方案(但我不喜欢):
解决方案1 模仿引擎盖下的内容
解决方案2 框架增强处理CM
在框架中添加“上下文工作模式”(标志,无论......),“start_benchmarking”流程将如下所示:
#Pseudo Code - Don't expect it to run
def start_benchmarking(self):
first() #including instantiating the context manager
ctx = get_the_context_manager_created_in_first()
with ctx ...:
t0 = take_time
for i in range(n_loops):
critical()
t1 = take_time
self.time = (t1-t0)/n_loops
value = end()
self.returned_value = value
任何其他更优雅的解决方案?
答案 0 :(得分:0)
def run_func_n_times(n_times, func, *args, **kwargs):
start = time.time()
for _ in range(n_times):
res = func(*args, **kwargs)
return res, (time.time() - start) / n_times
不需要一个类,只需一个简单的函数:
def example():
do_begin()
print('look, i am here')
with ctx() as blah:
res, timed = run_func_n_times(27, f, foo, bar)
do_end()