【问题标题】:How to drain/exhaust async generator at ~C speed?如何以 ~C 速度排空/耗尽异步发电机?
【发布时间】:2019-08-27 12:52:50
【问题描述】:

目前我正在使用async for _ in asyncgen(): pass

我正在寻找“快速路线”实现,同步生成器的方法是:

deque(maxlen=0).extend(generator)

【问题讨论】:

  • 经过快速基准测试后,deque(maxlen=0).extend(gen) 似乎比for _ in gen: pass 快​​了大约 20%。 deque 方法的 C 优化似乎不是这里的瓶颈:)
  • 我不明白。我知道双端队列消耗生成器的速度比其他任何东西都快。我希望为 async 生成器做同样的事情,deque 不能使用它,afaik
  • 我的意思是,20% 的加速并不是切换到基于 C 的方法所期望的(我通常期望像 10 倍的因子改进)。那是因为瓶颈在其他地方:缓慢的部分不是生成器的耗尽,而是该生成器中 python 代码的执行。我的建议是不要打扰并使用for _ in gen: passasync for _ in agen
  • 请注意,双端队列并不总是更快;一个简单的for 循环对小序列更有效。 (在我的机器上,截止点大约是 16 个元素。)

标签: python async-await generator python-asyncio


【解决方案1】:

不是您的问题的答案:

对于普通生成器,deque 似乎只比 for-loop 快slightly(超过 10%)。有人可能会争辩说,使用 deque 不会带来任何实际优势,也不值得它的不可靠性和可能的​​副作用。

但是当我们谈论异步编程时,它变得更加重要。 Word async 告诉我们在这个异步生成器内部发生了一些 I/O:否则首先有 no reason 使这个生成器异步。此 I/O 可能会占用 99% 的执行时间(请参阅this answer,尤其是那里的最后一个代码 sn-p)。它将 10% 的快速迭代优势转化为完全可悲的东西。

在优化所有努力之后,我们不会看到异步 for 循环和替代方法之间有任何可衡量的差异。

一般来说,“过早的优化是万恶之源”,只有“3% 的关键代码”is worth optimizing。哪 3% 只能在测量之后才能说出来,而当涉及到异步编程时,它可能是 I/O 的东西,而不是迭代。


您的问题的答案:

deque 比 for 循环运行得更快,只是因为它在 C 中是 implemented。没有(我知道)C 实现可用于异步迭代的类似函数。因此,如果您不想编写 C 代码,恐怕async for _ in asyncgen(): pass 是您现在唯一的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    相关资源
    最近更新 更多