迭代生成器的循环的Cython优化

4
我有很多使用 Python 生成器消耗数据的循环,其中一些还会重新 yield 处理过的数据。这是一个瓶颈,我想加速这部分代码,考虑使用 Cython。
那么如何处理生成器和 yield 呢?我希望:
  • 不用数据复制就能将 Python 生成器转换成 Cython
  • 让 Cython 的 for 循环消耗由 Python 生成器产生的数据
  • 像生成器一样 yield 数据
我猜这是一个常见的用例,那么建议采用什么方法呢?

你需要提供更多细节...另外,请解释为什么您认为使用Cython是正确的方法。可能有更好的解决方案。 - shx2
如果您在搜索Cython错误“yield not supported here”时被引导到此处,请确保您编写的是def而不是cpdef:https://groups.google.com/forum/#!topic/cython-users/DSJ_DlwCHHw - 0 _
1个回答

7

一些建议:

  • Cython支持生成器,因此您应该尝试将带有生成器的Python代码传递给cython并查看您获得的加速效果。
  • 下一步是在循环中添加尽可能多的静态类型信息以加快生成器执行的速度。
  • Python生成器很酷,但如果性能很重要,则它们不是完成任务的最快方法。您最好将瓶颈转换为使用连续数组。
  • 请查看Cython的类型化内存视图。
  • 您还可以使用Cython与C++ std :: vectors和其他高性能容器对象。

我们需要更多关于您的目标和限制的信息,以便在此提供更多帮助。一个简化的示例将非常有帮助。


我有一些长度未知的流水线。在这种情况下,生成器和协程可以使代码更加简洁。我将尝试使用Cython来使用生成器,这是一个新的添加吗? - san
为了达到所需的性能,您可能需要在代码的纯度上做出妥协。由于C语言不支持生成器,因此Cython必须引入相当数量的额外调用来使它们工作。尽管如此,它们仍然比纯Python生成器更快。在C语言中,数组非常快,因此您可以从中获得更好的性能。 - lothario
2
你可以考虑使用混合缓冲解决方案:你可以存储一个C数组或类型化的内存视图,对它们进行批量计算,然后逐个产生结果。这样你就可以保持流式算法,但又能从数组和连续内存访问的性能中获益。 - lothario
是的,这些流确实被缓冲并按照您所说的方式产生。C语言选择不包含协程抽象确实令人遗憾。您能否指向Cython中yield的权威文档?谷歌搜索结果给出了相互矛盾的声明,可能是因为这个功能是后来添加的。 - san
你能指引我到Cython中yield的权威文档吗?这是我关闭问题并接受答案所需要的,感谢你的回答。 - san

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接