使用Python / C接口而不是Cython是否有优势?

时间:2011-04-19 17:27:18

标签: python c numpy cython

我想通过使用BLAS和LAPACK在C或C ++中编写一些模块来扩展python和numpy。我还希望能够将代码作为独立的C / C ++库进行分发。我希望这个库使用单精度和双精度浮点数。我将编写的函数的一些示例是用于求解线性系统或加速一阶方法的共轭梯度。有些函数需要从C / C ++代码调用Python函数。

在使用Python / C API和Numpy / C API玩一点后,我发现许多人主张使用Cython(例如参见this questionthis one)。我不是Cython的专家,但似乎对于some cases,你仍然需要使用Numpy / C API并知道它是如何工作的。鉴于我已经拥有(一些)关于Python / C API的知识而没有关于Cython的知识,我想知道继续使用Python / C API是否有意义,并且如果使用此API比Cython有一些优势。在未来,我肯定会开发一些不涉及数值计算的东西,所以这个问题不仅仅是关于numpy。我喜欢Python / C API的一个原因是我学习了一些关于Python解释器如何工作的东西。

感谢。

3 个答案:

答案 0 :(得分:76)

当前的“最佳答案”听起来有点像我耳朵里的FUD。首先,平均开发人员在C中编写的代码比NumPy + Cython给你的代码要快得多。恰恰相反,在Python环境中获得必要的C代码以正常工作所需的时间通常更好地投入到在Cython中编写快速原型,对其进行基准测试,优化它,以更快的方式重写它,对其进行基准测试再次,然后决定其中是否有任何东西真正需要5-10%的性能,你可能会或可能不会从手动调整的C中重写2%的代码并调用它从您的Cython代码。

我正在用Cython编写一个库,目前有大约18K行的Cython代码,它可以转换成近200K行的C代码。通过在正确的位置注入大约20行手动调整的C代码,我曾经设法通过几个非常重要的内部基本级功能加速了近25%的速度。我花了几个小时来重写和优化这个小部件。与我节省的大量时间相比,这一点真的没什么,因为我们首先没有在普通的C中编写(并且必须维护)库。

即使您比Cython更了解C,如果您了解Python C,您将很快学会Cython,无论如何都值得投资,特别是当您进入数字时。您编写的80-95%的代码将从高级语言编写中受益匪浅,您可以安全地放松并投入一半的时间来保存代码,就像编写代码一样快用一种低级语言马上开始。

话虽如此,您希望“能够将代码作为独立的C / C ++库分发”的评论是坚持普通C / C ++的正当理由。 Cython总是依赖于CPython,这是一种依赖。但是,使用普通的C / C ++(Python接口除外)也不允许你利用NumPy,因为这也取决于CPython。因此,像往常一样,在用C语言编写内容时,在进入实际功能之前,您必须做很多基础工作。在开始这项工作之前,你应该认真考虑这两次。

答案 1 :(得分:8)

首先,你的问题中有一点我没有得到:

  

[...]也希望能够将代码作为独立的C / C ++库进行分发。 [...]某些函数需要从C / C ++代码调用Python函数。

这应该如何运作?

接下来,关于您的实际问题,直接使用Python / C API肯定有优势:

  • 最有可能的是,编写C代码比编写Cython代码更熟悉。

  • 用C编写代码可以最大限度地控制。要从Cython代码获得与等效C代码相同的性能,您必须非常小心。你不仅需要确保声明所有变量的类型,还需要充分设置一些标志 - 只有一个例子是bounds checking。您需要了解Cython如何努力获得最佳性能。

  • Cython代码依赖于Python。在Cython中编写也应该作为独立C库分发的代码似乎不是一个好主意

答案 2 :(得分:0)

Python / C API的主要缺点是如果它在内部循环中使用它会非常慢。我看到调用一个Python函数比调用一个等效的C ++函数需要80-160倍。

如果这不会打扰你的代码,那么你就可以在Python中编写一些代码块,访问Python库,支持直接用Python编写的回调。这也意味着您可以在不重新编译的情况下进行一些更改,从而使原型设计更容易。