如何衡量Python的asyncio代码性能?

问题描述 投票:11回答:2

我不能使用常规工具和技术来衡量协程的性能,因为不应该考虑await所花费的时间(或者它应该只考虑从等待但不是IO延迟读取的开销)。

那么如何衡量协程所需的时间呢?我如何比较2个实现并找到更高效的?我使用什么工具?

python performance-testing trace python-asyncio
2个回答
14
投票

这个答案最初包含两个不同的解决方案:第一个解决方案基于猴子修补,第二个解决方案不适用于python 3.7及更高版本。这个新版本有望呈现更好,更强大的方法。

首先,标准计时工具(如time)可用于确定程序的CPU时间,这通常是我们在测试异步应用程序性能时感兴趣的。这些测量也可以使用time.process_time()函数在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

在asyncio应用程序中,可能会发生程序的某些同步部分最终执行阻塞调用,从而有效地阻止事件循环运行其他任务。因此,我们可能希望单独记录事件循环从其他IO任务所花费的时间等待的时间。

这可以通过继承default selector来执行某些定时操作并使用custom event loop policy来设置所有内容来实现。 This code snippet提供了这样的策略以及用于打印不同时间度量的上下文管理器。

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

另请注意,asyncio debug mode可以检测到这些阻塞操作:

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

0
投票

如果你只想测量“你的”代码的性能,你可以使用类似于单元测试的方法 - 只需猴子补丁(甚至补丁+模拟)最接近的IO协程与期望结果的未来。

主要缺点是例如http客户端相当简单,但让我们说momoko(pg客户端)......如果不知道它的内部结构可能很难做到,它不会包含库开销。

专业人士就像在普通测试中一样:

  • 它很容易实现,
  • 它测量的东西;),主要是一个没有第三方库开销的实现,
  • 性能测试是孤立的,易于重新运行,
  • 这是运行许多有效载荷
© www.soinside.com 2019 - 2024. All rights reserved.