e-s*_*tis 12 python trace performance-testing python-asyncio
我不能使用常规工具和技术来测量协程的性能,因为它await不应该考虑它所花费的时间(或者它应该只考虑从等待但不是IO延迟读取的开销).
那么如何衡量协程所需的时间呢?我如何比较2个实现并找到更高效的?我使用什么工具?
Vin*_*ent 15
一种方法是修补__CODE__以便计时并保存所有IO操作.这可以使用上下文管理器完成:
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")
Run Code Online (Sandbox Code Playgroud)
然后使用另一个上下文管理器为完整运行计时,并计算总时间和IO时间之间的差异:
$ /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
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子:
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)
Run Code Online (Sandbox Code Playgroud)
它打印以下报告:
~ 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
Run Code Online (Sandbox Code Playgroud)
编辑
另一种方法是子类化__CODE__并覆盖该__CODE__方法以计算步骤的执行时间:
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
Run Code Online (Sandbox Code Playgroud)
然后可以将子类注册为默认任务工厂:
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")
Run Code Online (Sandbox Code Playgroud)
同样的例子:
$ /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
Run Code Online (Sandbox Code Playgroud)
随着输出:
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)
Run Code Online (Sandbox Code Playgroud)