我想测量发生器花费的时间(阻塞主循环的时间)。
假设我有以下两个生成器:
async def run():
for i in range(5):
await asyncio.sleep(0.2)
yield i
return
async def walk():
for i in range(5):
time.sleep(0.3)
yield i
return
我想测量run
每次迭代花费大约0.0s
,而walk
至少使用0.3s
。
我想使用类似于this的东西,但无法让它为我工作。
澄清:
我想排除在任何await
部分花费的时间。如果因为某种原因协程停止了,那么我不想考虑这段时间。
2条答案
按热度按时间pxyaymoc1#
所以-一件事(虽然有点)是在常规的协同例程中测量时间-我用装饰器来实现它。
然而,当你进一步进入异步生成器时,它是另一个野兽-我仍在试图弄清楚-它是公共暴露的异步迭代器方法(
__anext__
,asend
等...)与返回对象中的传统迭代器方法的混合,我还不能弄清楚(我刚刚打开PEP 525,看看我是否能理解它)。至于常规的协同例程,有一个问题:如果你创建了一个可等待类(我的decorator),asyncio将要求它的
__await__
方法返回一个__next__
方法,这个方法将被调用。但是原生Python协同例程没有__next__
:asyncio在这些上调用send()
--所以我必须做这个“转置”,以便能够测量时间(在协同例程中)。如果我能弄清楚如何 Package 异步生成器,* 也许 * 会继续。
(我认为大多数现有的分析工具使用语言中可用的工具进行调试和跟踪(通过
sys.settrace()
启用:所有的东西在回调中都是“可见的”,不用担心 Package 所有的内部调用(由async机制和asyncio循环进行)...所以,这里是在异步生成器中捕获时间的代码。
它会得到一个好的路径-如果有复杂的等待类,实现或使用
asend
,athrow
,这不会做-但对于一个简单的异步生成器函数plugget到async for
语句,它现在工作:免责声明:在下面的代码中可能有未使用的代码,甚至是未使用的状态--我来回了很多次才让它工作(很多是因为我没有尝试
__anext__
本身必须是异步的)。尽管如此,还是这样:myzjeezk2#
为什么不使用Profiler?
yappi
非常擅长分析,尤其是coroutine
s。