性能上扩展python / numpy的最佳方法

因为有很多方法可以为python编写二进制模块,所以如果我希望尽可能地提高代码的某些段的性能,那么我可以根据经验提出最佳方法的建议。

据我所知,可以使用python / numpy C-api编写扩展,或者包装一些已经编写的纯C / C ++ / Fortran函数,以便从python代码中调用。

当然,像Cython这样的工具是最简单的方法,但我认为手动编写代码可以提供更好的控制并提供更好的性能。

问题,也可能是一般性的,是使用哪种方法。 写一个C或C ++扩展名? 包装外部C / C ++函数或使用回调到python函数?

我在阅读Langtangen的“计算科学的Python脚本”第10章后写了这个问题,其中有几种方法可以比较python和C之间的接口。

我会说这取决于你的技能/经验和你的项目。 如果这是非常有意义的并且您熟练使用C / C ++并且您已经编写了python包装器,那么请编写自己的扩展并对其进行接口。

如果您打算在其他项目中使用Numpy,那么请使用Numpy C-API,它的内容非常丰富且文档齐全,但它也需要处理很多文档。 至少我在处理它时遇到了很多困难,但是我又一次在C处吮吸。

如果你不确定去Cython,那么耗时少得多,而且在大多数情况下性能都非常好。 (我的选择)从我的角度来看,你需要成为一名优秀的C编码器才能比以前的2实现更好地运行Cython,而且它会更加复杂和耗时。 你是一个伟大的C编码器吗?

如果您正在寻找性能,那么考虑到pycuda或其他一些GPGPU的东西也可能值得您花些时间,具体取决于您的硬件。

可以在这里找到几种不同方法的良好比较。 我已经尝试了两个cython,并使用f2py包装我自己的fortran代码。 我发现f2py是更适合我的目的。 这部分受到我理解fortran这一事实的影响,但老实说现代方言如fortran 90看起来与使用numpy的python代码相似,并且不应该那么难以接受。

使用cython开始使用缓慢,纯粹的python代码,然后你必须经历一个繁琐的代码检测过程,找出所有对python API的调用,并在正确的位置输入相关的cython关键字它变成了更快的C代码。 使用fortran,您只需编写正常的代码,并且您已经获得了完整的编译速度,而无需进行混乱的迭代过程。

此外,cython中的某些数组操作仍会导致对Python API的调用速度变慢,特别是那些涉及切片操作的调用。 相比之下,fortran中的数组是编译器理解并可以优化的本机类型。 话虽如此,cython正在迅速发展,所以未来可能会发生变化。

我发现f2py的最大缺点是它不支持派生类型的数组(类似于numpy的重新排列)。 有一些希望fwrap可以替代f2py来解决这个问题,但它现在似乎已经退缩了。 顺便说一句,它基于cython。