PEP 380提到可以在Python中优化yield from expr
语法。
当存在长链生成器时,使用专门语法为优化提供了可能性。例如,当递归地遍历树结构时,可能出现这样的链。传递
__next__()
次调用并在链中向上和向上产生值的开销可能导致应该是O(n)操作,在最坏的情况下,O(n ** 2)。可能的策略是向生成器对象添加一个槽以保存委派给它的生成器。当在生成器上进行
__next__()
或send()
调用时,首先检查此插槽,如果它是非空的,则引用它引用的生成器。如果它引发StopIteration
,则清空插槽并恢复主发生器。这将减少一系列C函数调用的委托开销,这些调用不涉及Python代码执行。可能的增强是遍历循环中的整个生成器链并直接恢复最后的生成器,尽管
StopIteration
的处理比较复杂。
CPython是否实现了此优化?
答案 0 :(得分:2)
看起来不像。从Python 3.6开始,generator object structure没有建议的字段,yield from
通过一系列生成器的代码路径总是经历单独恢复其Python堆栈帧的过程。 (此代码路径从YIELD_FROM
操作码到_PyGen_Send
/ gen_iternext
到gen_send_ex
,从那里到PyEval_EvalFrameEx
再到YIELD_FROM
链中的下一个发电机。)