3

PEP 380提到yield from expr可以在 Python 中优化语法。

PEP 380 - 优化

当存在一长串生成器时,使用专门的语法为优化提供了可能性。例如,当递归遍历树结构时,可能会出现这种链。向下和向上传递 __next__() 调用和生成值的开销可能导致本应为 O(n) 的操作在最坏的情况下变为 O(n**2)。

一种可能的策略是向生成器对象添加一个槽,以保存被委托的生成器。当在生成器上进行 __next__() or send() 调用时,首先检查此插槽,如果它非空,则恢复它引用的生成器。如果它升起StopIteration,则清除槽并恢复主发电机。

这将减少对不涉及 Python 代码执行的 C 函数调用链的委托开销。一个可能的改进是在一个循环中遍历整个生成器链并直接在最后恢复一个,尽管处理StopIteration更复杂。

CPython 是否实现了这种优化?

4

1 回答 1

2

看起来不像。从 Python 3.6 开始,生成器对象结构没有建议的字段,并且yield from通过生成器链的代码路径总是经历单独恢复其 Python 堆栈帧的过程。(此代码路径从YIELD_FROM操作码通过_PyGen_Send/gen_iternextgen_send_ex,然后从那里到PyEval_EvalFrameExYIELD_FROM中的下一个生成器。)

于 2017-04-24T16:43:32.220 回答