我不能使用正常的工具和技术来衡量协同器的性能,因为它在await
上所花费的时间不应该被考虑(或者它应该只考虑从可访问的,而不是IO延迟中读取的开销)。
那么,如何衡量协同作用所需的时间呢?如何比较两个实现并找到更有效的实现?我该用什么工具?
发布于 2016-01-16 13:04:48
这个答案最初包含两种不同的解决方案:第一种基于猴子补丁,第二种则不适用于python3.7和以后的版本。这个新版本有望提供一种更好、更健壮的方法。
首先,可以使用标准的计时工具(如时间 )来确定程序的CPU时间,这通常是我们在测试异步应用程序的性能时感兴趣的。还可以使用时间()函数在python中执行这些测量:
import time
real_time = time.time()
cpu_time = time.process_time()
time.sleep(1.)
sum(range(10**6))
real_time = time.time() - real_time
cpu_time = time.process_time() - cpu_time
print(f"CPU time: {cpu_time:.2f} s, Real time: {real_time:.2f} s")
见下面这两种方法产生的类似产出:
$ /usr/bin/time -f "CPU time: %U s, Real time: %e s" python demo.py
CPU time: 0.02 s, Real time: 1.02 s # python output
CPU time: 0.03 s, Real time: 1.04 s # `time` output
在异步应用程序中,程序的某些同步部分可能会执行阻塞调用,从而有效地阻止事件循环运行其他任务。因此,我们可能需要分别记录事件循环从其他IO任务所花费的等待时间。
这可以通过子类默认选择器来执行一些定时操作和使用自定义事件循环策略来设置一切来实现。这个代码片段提供了这样的策略以及用于打印不同时间度量的上下文管理器。
async def main():
print("~ Correct IO management ~")
with print_timing():
await asyncio.sleep(1)
sum(range(10**6))
print()
print("~ Incorrect IO management ~")
with print_timing():
time.sleep(0.2)
await asyncio.sleep(0.8)
sum(range(10**6))
print()
asyncio.set_event_loop_policy(TimedEventLoopPolicy())
asyncio.run(main(), debug=True)
请注意这两次运行之间的差异:
~ Correct IO management ~
CPU time: 0.016 s
Select time: 1.001 s
Other IO time: 0.000 s
Real time: 1.017 s
~ Incorrect IO management ~
CPU time: 0.016 s
Select time: 0.800 s
Other IO time: 0.200 s
Real time: 1.017 s
还请注意,异步调试模式可以检测到那些阻塞操作:
Executing <Handle <TaskWakeupMethWrapper object at 0x7fd4835864f8>(<Future finis...events.py:396>) created at ~/miniconda/lib/python3.7/asyncio/futures.py:288> took 0.243 seconds
发布于 2016-01-17 14:37:03
如果你只想衡量“你的”代码的性能,你可以使用类似于单元测试的方法--仅仅是猴子补丁(甚至补丁+模拟)最近的IO协同与预期结果的未来。
主要的缺点是http客户端非常简单,但是假设momoko (pg客户端).如果不知道它的内部结构,就很难做到,它将不包括库开销。
专业人士就像普通测试一样:
https://stackoverflow.com/questions/34826533
复制相似问题