【问题标题】:Are there advantages to use the Python/C interface instead of Cython?使用 Python/C 接口而不是 Cython 是否有优势?
【发布时间】:2011-08-08 21:09:55
【问题描述】:

我想通过使用 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 解释器工作原理的知识。

谢谢。

【问题讨论】:

  • 如果我没记错的话,BLAS 和 LAPACK 已经集成在 scipy 中了
  • 注意:您为 some cases 提供的链接指向使用来自 Cython 而非 C 的 Numpy/C API 的代码。
  • @fabrizioM:是的,BLAS 和 LAPACK 用于 numpy 和 scipy。但是我想开发既不是 numpy 也不是 scipy 的数值算法,出于效率原因,我想在 C/C++ 中进行。
  • @J.F.塞巴斯蒂安:是的。我的观点是,这段代码非常接近使用 Numpy/C API 编写的 C 代码:必须知道底层行为(如引用计数)。

标签: python c numpy cython


【解决方案1】:

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

如果这不会影响您的代码,那么您将受益于能够用 Python 编写一些代码块、可以访问 Python 库、支持直接用 Python 编写的回调。这也意味着您可以在不重新编译的情况下进行一些更改,从而使原型制作更容易。

【讨论】:

  • 您不会在 Python 中编写紧密的循环。你用 C 编写紧密的循环,然后将它们连接到 Python。
【解决方案2】:

首先,你的问题中有一点我不明白:

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

这应该如何工作?

接下来,关于你的实际问题,直接使用 Python/C API 肯定有好处:

  • 很可能,您更熟悉编写 C 代码而不是编写 Cython 代码。

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

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

【讨论】:

  • “这应该如何工作?” -- 通常的方法是嵌入Python解释器,不是吗?
  • @Nicholas:我不知道这是否是 OP 计划做的。也许需要调用 Python 函数的函数根本不会成为 C 库的一部分?一些澄清会很好。 (而且我知道这第一部分更多的是评论而不是答案,但是由于无论如何我都在写答案,所以我把它放在那里是为了更好地格式化。)
  • 你提出的观点确实不是很清楚。我的意思是我的库中的一些函数将用户定义的函数作为参数。 Python 用户将在 Python 中定义这些函数,而 C/C++ 用户将使用 C/C++ 中的函子。这更清楚了吗?
  • 此外,Cython 似乎并没有给你完全的安全/可移植性,因为它的类型系统与 C 相比相当贫乏(尽管 size_t 最终是在 0.11 中添加的)。
【解决方案3】:

当前的“最佳答案”在我耳中听起来有点像 FUD。一方面,普通开发人员用 C 编写的代码比 NumPy+Cython 给你的代码更快并不是很明显。恰恰相反,将必要的 C 代码在 Python 环境中正常工作所花费的时间通常更好地投资于在 Cython 中编写快速原型、对其进行基准测试、对其进行优化、以更快的方式对其进行重写、对其进行基准测试再次,然后决定其中是否有真正需要提高 5-10% 性能的东西来自您的 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 编写东西时,您必须先做很多基础工作,然后才能使用实际功能。在开始这项工作之前,您应该认真考虑一下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多