如何度量Python';异步IO代码的性能如何? 我不能用普通的工具和技术来衡量一个协同程序的性能,因为在代码>等待< /COD>时不应该考虑(或者它应该只考虑从可读取的开销,而不是IO等待时间)。

如何度量Python';异步IO代码的性能如何? 我不能用普通的工具和技术来衡量一个协同程序的性能,因为在代码>等待< /COD>时不应该考虑(或者它应该只考虑从可读取的开销,而不是IO等待时间)。,python,performance-testing,trace,python-asyncio,Python,Performance Testing,Trace,Python Asyncio,那么,如何度量一个协同程序所花费的时间呢?如何比较两种实现并找到更有效的实现?我应该使用什么工具?这个答案最初包含两种不同的解决方案:第一种基于monkey补丁,第二种不适用于python 3.7及以后的版本。这个新版本有望提供一个更好、更健壮的方法 首先,可以使用标准计时工具(如)确定程序的CPU时间,这通常是我们在测试异步应用程序性能时感兴趣的。这些测量也可以在python中使用以下函数执行: import time real_time = time.time() cpu_time = t

那么,如何度量一个协同程序所花费的时间呢?如何比较两种实现并找到更有效的实现?我应该使用什么工具?

这个答案最初包含两种不同的解决方案:第一种基于monkey补丁,第二种不适用于python 3.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
在asyncio应用程序中,程序的某些同步部分可能会执行阻塞调用,从而有效地阻止事件循环运行其他任务。因此,我们可能需要分别记录事件循环等待的时间和其他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
执行耗时0.243秒

如果您只想测量“您的”代码的性能,您可以使用类似于单元测试的方法-只需monkey patch(甚至patch+Mock)就可以得到预期结果的最近IO协同程序

主要的缺点是,例如http客户端相当简单,但让我们假设momoko(pg客户端)。。。如果不了解它的内部结构,就很难做到这一点,因为它不会包括库开销

pro与普通测试一样:

  • 它很容易实现
  • 它测量某物;),主要是一个人的实现,没有第三方库的开销
  • 性能测试是隔离的,易于重新运行
  • 它需要与许多有效载荷一起运行

我将升级投票,因为它可以工作,但它非常粗糙,在下一次python升级时可能会中断。@e-satis请参阅我的编辑,了解另一种方法,不那么粗糙。