有关使用C扩展或Cython优化非平凡Python应用程序的教程

时间:2010-11-15 22:08:11

标签: python c optimization cython python-extensions

Python社区发布了有用的参考资料,展示了如何分析Python代码,以及C语言或Cython中Python扩展的技术细节。我仍然在寻找教程,但是,对于非平凡的Python程序,显示如下:

  1. 如何通过转换为C扩展来识别将从优化中受益的热点
  2. 同样重要的是,如何识别从转换为C扩展程序中受益的热点
  3. 最后,如何使用Python C-API或(甚至最好)使用Cython进行从Python到C的适当转换。
  4. 一个好的教程将为读者提供一种方法,通过一个完整的例子来说明如何推理优化问题。我没有成功找到这样的资源。

    你知道(或有你写过)这样的教程吗?

    为了澄清,我对仅涵盖以下

    的教程不感兴趣:

    • 使用(c)配置文件来分析Python代码以测量运行时间
    • 使用工具检查配置文件(我建议RunSnakeRun
    • 通过选择更合适的算法或Python结构进行优化(例如,设置成员资格测试而不是列表);教程应该假设算法和Python代码已经是最优的,我们正处于C扩展是下一个逻辑步骤的时刻
    • 重述Python documentation on writing C extensions,它已经很好地作为参考,但没有用作显示何时以及如何从Python迁移到C的资源。

4 个答案:

答案 0 :(得分:9)

第1点和第2点只是拇指的基本优化规则。如果您正在寻找任何类型的教程,我会非常惊讶。也许这就是你没找到的原因。我的简短名单:

  • 优化的第一条规则
  • 第二条规则措施
  • 规则编号3 识别限制因素(如果是IO或数据库绑定,则无论如何都无法进行优化)。
  • 第四条规则是认为使用更好的算法和数据结构 ...
  • 考虑到名单上的语言变化很低......

首先使用usual python tools分析您的python代码。找到您需要优化的代码。然后尝试优化它坚持使用python。如果它仍然太慢,试着理解为什么。如果它受IO限制,则C程序不太可能更好。如果问题来自算法,那么C也不太可能表现得更好。实际上C可以提供帮助的“好”案例非常少见,运行时不应该离你想要的太远(比如3倍加速中的2倍)数据结构很简单并且会受益于低级别的表示,你真的,真的需要加速。在大多数其他情况下,使用C而不是python将是一项无益的工作。

真的很少见python中的C代码是以性能为主要目标完成的。更常见的目标是将python与一些现有的C代码接口。

正如另一张海报所说,你可能会更好地建议使用cython。

如果您仍想为Python编写C模块,则所有必要的内容都在official documentation.

答案 1 :(得分:6)

O'Reilly has a tutorial(据我所知,我可以自由阅读,我能够阅读整个内容),它说明了如何分析真实项目(他们使用EDI解析项目作为分析主题)并识别热点。编写C扩展名没有太多细节可以解决O'Reilly文章中的瓶颈问题。但是,它确实涵盖了你想要的前两件事,并带有一个非常重要的例子。

编写C扩展的过程记录良好here。困难的部分是提出了复制Python代码在C中所做的事情的方法,并且需要教程中难以教授的东西:独创性,算法知识,硬件和效率,以及相当多的C技能。

希望这有帮助。

答案 2 :(得分:4)

对于第1点和第2点,我会使用Python分析器,例如cProfile。有关快速教程,请参阅here

如果您已经有一个已经存在的python程序,对于第3点,您可能需要考虑使用Cython。当然,您可以考虑改进执行速度的算法改进,而不是用C语言重写。

答案 3 :(得分:2)

我会尝试解决你的第1点和第2点,以及你的前3个要点,但不是按顺序。

第三个要点是“假设算法和python代码已经是最优的”。当代码处于该状态时,如果采用堆栈样本(as outlined here),则样本会从时间角度准确显示程序正在执行的操作,并且似乎没有任何内容可以在没有语言更改的情况下得到改进。但是,既然你知道它是如何花费时间的,你知道哪个低级算法(可能包含多个函数,而不仅仅是一个热点)可以通过减少时间来获益,即通过转换为C

关于第1点,此方法显示代码的哪些部分将通过转换为C而受益,并且它们可能是也可能不是热点。 (首先想到的是任何类型的递归函数或函数集。或者,一小组函数共同实现某些目的,例如爬山者。)

关于第2点,任何没有出现在堆栈样本的健康百分比上的代码,或者通过转换为C而显然不会受益的任何代码,例如I / O.

关于第一和第二个要点,我同意测量不是主要目标,而是找到优化代码的过程的副产品。提出这样的测量也是不重要的。

我遇到过类似的情况,除了python和C之间,但C和硬件之间没有。**

举一个例子,如果总运行时间是10秒,并且算法大约50%的时间在堆栈上,那么它在10秒内大约有5个负责。如果将算法转换为C将提供10倍的加速,那么5秒将缩小到0.5秒,因此总时间将缩小到5.5秒。 (粗略地说 - 实现时间减少比预先确切知道它有多大是更重要的。)注意,此时整个过程可以重复,并且将其他东西转换为C也可能是有意义的。 当样本显示python代码正在做它擅长的事情时,你可以停止这个过程,并且C代码正在做它擅长的事情。

**浮点数学,库与芯片或图形,绘图文本和多边形。