1 回答
TA贡献1858条经验 获得超8个赞
这里有几个问题,如果可能的话应该避免。但对于你的前两个问题有一个简单的答案。为什么它固定单个CPU,为什么在打印进度条之前有延迟?有很多单线程工作要做。
asyncio
在单个线程中运行所有内容,除非您明确这样做。您正在构建的任务需要在 内部进行大量设置asyncio
,尤其是对as_completed
. 但它必须:
创造
set
你的未来。不太贵,但不是免费的。设置生产者和消费者队列来控制尚未运行的任务和已完成的任务。对于您正在使用的如此大量的任务,这可能会导致多次、大量的分配,这可能是一个真正的杀手。
安排回调在 future 完成时运行。这主要是将它们从队列移动到另一个队列,并将它们从
set
future 中删除,这些都不是免费的。成就每一个未来
事实上,这里有很多设置,并且这需要相当多的时间,通过改变输入的大小可以很容易地看到这一点。在我的笔记本电脑上,运行任何期货之前的时间确实从 size 开始急剧下降100000
。此外,它会非线性下降,这表明这个大小对于我的机器上的内存层次结构特别不利(例如,在这个大小之后,会有更多的缓存未命中)。
asyncio
我还发现事件循环的解析可能在这里发挥了作用。期货的消耗必须经过一定的时间。您正在创建许多 future,其中许多几乎是在事件循环的单个滴答内同时完成的(正如 @user4815162342 在评论中正确指出的那样)。事件循环的每个周期都有大量工作,并且必须全部在单个线程上完成。
考虑到整个事情需要超过 1 秒才能完成这一事实,这一点非常清楚。最大睡眠间隔为 1 秒,因为random.random
为您提供了 上的值[0, 1.0)
,但整个应用程序需要更长的时间。因此,这里正在进行的工作不仅仅是“一秒钟的价值”,而且全部都在一个线程中进行。
添加回答
举报