如何对Python ASYNCIO代码进行性能分析/基准测试?

7

我该如何对使用ASYNCIO的Python异步脚本进行性能分析/基准测试?

通常情况下,您可以执行以下操作:

totalMem = tracemalloc.get_traced_memory()[0]
totalTime = time.time()

retValue = myFunction()

totalTime = time.time() - totalTime 
totalMem = tracemalloc.get_traced_memory()[0] - totalMem 

这样做可以节省函数所需的总时间。我学会了如何使用装饰器,并将所有统计数据转储到文本文件中以供日后分析。
但是,当您有ASYNCIO脚本时,情况就大不同了:函数在执行 "await aiohttpSession.get()" 时会阻塞,控制权将返回事件循环,该循环将运行其他函数。
这样,经过的时间和总分配内存的变化就无法揭示任何信息,因为我测量的不仅仅是那个函数。
唯一可行的方法可能是像这样:
class MyTracer:
  def __init__(self):
    self.totalTime = 0
    self.totalMem = 0
    self.startTime = time.time()
    self.startMem = tracemalloc.get_traced_memory()[0]
  def stop(self):
    self.totalTime += time.time() - self.startTime
    self.totalMem += tracemalloc.get_traced_memory()[0] - self.startMem
  def start(self):
    self.startTime = time.time()
    self.startMem = tracemalloc.get_traced_memory()[0]

现在,以某种方式将其插入到代码中:

def myFunction():

    tracer = MyTracer()

    session = aiohttp.ClientSession()

    # do something

    tracer.stop()
    # the time elapsed here, and the changes in the memory allocation, are not from the current function
    retValue = await(await session.get('https://hoochie-mama.org/cosmo-kramer',
        headers={
            'User-Agent': 'YoYo Mama! v3.0',
            'Cookies': 'those cookies are making me thirsty!',
            })).text()
    tracer.start()

    # do more things

    tracer.stop()

    # now "tracer" has the info about total time spent in this function, and the memory allocated by it
    # (the memory stats could be negative if the function releases more than allocates)

有没有一种方法可以实现这个,我的意思是,在不必插入所有这些代码的情况下对我的所有异步代码进行分析? 或者已经有一个模块能够做到这一点了吗?
2个回答

1

请查看Yappi profiler,它支持协程分析。他们的协程分析页面非常清楚地描述了你面临的问题:

协程的主要问题在于,在幕后当协程暂停或换句话说进行上下文切换时,Yappi 就像我们从函数退出一样接收到返回事件。这意味着在协程处于 yield 状态时花费的时间不会累积到输出中。这对于墙上时间来说尤其是一个问题,因为在墙上时间中,您希望看到该函数或协程中花费的全部时间。另一个问题是调用计数。每次协程暂停时,都会增加调用计数,因为它是常规函数退出。

他们还非常高级地描述了 Yappi 如何解决这个问题:

通过 v1.2,Yappi 解决了协程分析中的上述问题。在幕后,它区分了 yield 和真实函数退出,并且如果选择 wall time 作为 clock_type,则会累积时间并纠正调用计数指标。


0

pyinstaller 也是一个很好的选择。你可以在 Github 上查看并阅读他们的 documentation

我作为一个模块尝试了它,结果看起来非常好,特别是以 HTML 格式呈现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接