有哪些工具或方法可用来加快用Python编写的代码的速度?


29

背景:我想我可能想移植一些使用Krylov子空间方法从MATLAB到Python来计算矩阵指数矢量乘积的代码。(具体来说,是Jitse Niesen的expmvp函数,该函数使用本文中介绍的算法。)但是,我知道,除非我大量使用了来自编译库的模块中的函数(即,我仅使用原始Python,并且没有很多内置的Python代码,在功能上),那么它可能会很慢。

问题:哪些工具或方法可用来帮助我加快用Python编写的代码的性能?特别是,我对使流程尽可能自动化的工具感兴趣,尽管也欢迎使用一般方法。

注意:我有一个较旧版本的Jitse算法,并且已经有一段时间没有使用它了。快速编写此代码可能很容易,但是我觉得它可以成为一个很好的具体示例,并且与我自己的研究有关。辩论我在Python中实现此特定算法的方法完全是另一个问题。


我给这个问题提供了一个Python 专用的答案:scicomp.stackexchange.com/questions/2429/...……我认为那里的提示和链接将对您有所帮助。
AlexE 2012年

(致@AlexE致使我意识到这一点)这个问题之间肯定存在重叠,(如何)编写运行速度更快的模拟?,还有哪些改善我的代码的串行性能的好的策略?。某种合并可能是有序的。我在Meta上发布了有关它的信息。
Geoff Oxberry 2012年

1
除了此处的好答案之外,请查看此链接
Mike Dunlavey 2012年

Answers:


40

我将答案分为三个部分。分析,通过c加快python代码的速度,并通过python加快python的速度。我认为Python拥有一些最好的工具,可用来查看您的代码的性能然后深入到实际的瓶颈。在不进行概要分析的情况下加速代码就像试图用uzi杀死一只鹿一样。

如果您真的只对mat-vec产品感兴趣,我建议scipy.sparse

用于剖析的Python工具

profile和cProfile模块:这些模块将为您提供标准的运行时分析和函数调用堆栈。保存他们的统计信息非常好,使用pstats模块,您可以通过多种方式查看数据。

kernprof:此工具汇集了许多例程,用于逐行代码计时

memory_profiler:此工具逐行生成代码的内存足迹

IPython计时器:该timeit函数非常适合以快速交互的方式查看函数中的差异。

加快Python

Cython:cython是在python中采用一些功能并获得更快代码的最快方法。您可以使用python的cython变体来装饰函数,并且它会生成c代码。这是非常可维护的,并且还可以很容易地链接到c / c ++ / fortran中的其他手写代码。到目前为止,它是当今首选的工具。

ctypes:ctypes允许您用c编写函数,然后用其简单的代码修饰快速包装它们。它处理了从PyObjects进行转换和管理gil调用c函数的所有痛苦。

还有其他方法可以用C编写代码,但是对于采用C / C ++库并将其包装在Python中的方法,则更多。

仅限Python的方法

如果您想主要留在Python中,我的建议是弄清楚您正在使用什么数据,并选择正确的数据类型来实现算法。根据我的经验,与其他任何底层c技巧相比,通过优化数据结构通常可以使您走得更远。例如:

numpy:非常快的连续数组,用于数组的跨步操作

numexpr:numpy数组表达式优化器。它允许多线程numpy数组表达式,并且由于python解释器的限制,还摆脱了numpy产生的大量临时变量。

blist:列表的b树实现,非常快地用于插入,索引和移动列表的内部节点

pandas:数据框(或表)对阵列的分析非常快。

pytables:快速结构化的分层表(如hdf5),特别适合于核心计算和对大数据的查询。


3
您也可以使用ctypes调用Fortran例程。
马修·埃米特


谈论包装代码,f2py呢?
astrojuanlu 2012年

f2py是一个很棒的工具,并被社区中的许多人使用。fwrap是更新的替代品,因为f2py显示了它的年龄,但还不是很完整。
aterrel 2012年

谢谢!这些是我一直在寻找的资源类型。我只知道其中一些,并且只是通过(或通过互联网查看它们)而已。Aron不断提及numexpr。这是如何运作的?那会适用吗?
Geoff Oxberry 2012年

7

首先,如果有可用的C或Fortran实现(MATLAB MEX函数?),为什么不编写Python包装器呢?

如果您希望自己的实现不仅是包装器,我强烈建议对线性代数使用numpy模块。确保将其链接到优化的bla(例如ATLAS,GOTOblas,uBLAS,Intel MKL等)。并使用Cython或编织。阅读此Performance Python文章以获得良好的介绍和基准。本文的不同实现可从Travis Oliphant(Numpy-guru)这里下载。

祝好运。


关于Performance Python的文章似乎有些陈旧,没有提及numexpr等一些较新的工具。
阿隆·艾玛迪亚

我确实忽略了numexpr。最好使用numexpr运行相同的laplace基准...
GertVdE 2012年

scipy.weave仍然使用和发展?Performance Python文章似乎表明它可以快速使用并且在速度上有相当不错的提高,但是我很少见到它在文章外部提到。
2012年

@肯:据我所知,scipy.weave不再处于活跃开发中。保留它是为了向后兼容,但鼓励新项目使用Cython。
GertVdE 2012年

有关GotoBLAS和NumPy / SciPy的信息,请参阅der-schnorz.de/2012/06/optimized-linear-algebra-andnumpyscipy
AlexE 2012年

4

基本上我同意其他答案。快速数字python代码的最佳选择是

  • 使用像 numpy
  • 包装您现有的代码,以便您的python-program可以直接调用它

但是,如果您想从头开始编写整个算法(我引用:“我只使用原始Python”),那么您可能需要考虑http://pypy.org/的JIT(及时)实现python。我无法在我的项目中使用它(因为要依靠它numpy,而pypy伙计们正在努力地支持它),但是基准测试相当出色(http://speed.pypy.org/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.