【问题标题】:Implementing a function in Python vs C在 Python 与 C 中实现函数
【发布时间】:2011-02-11 11:00:43
【问题描述】:

在 Python 中实现一个函数和在 C 中实现它然后从 Python 调用它之间有区别(就执行时间而言)?如果有,为什么?

【问题讨论】:

  • 呃,什么?对于初学者,您(通常)不编译 Python 并且无论如何都需要一个包装器来从 Python 调用 C 函数,反之亦然。对于稍微高级的用户,您是否意识到性能在很大程度上取决于算法,然后取决于实现(代码和语言实现),而不仅仅是语言? (您可以使用 LLVM/Clang 来解释 C 和 C++...以及几个项目来通过编译大大加快 Python 代码的速度)。更不用说许多人无法在可接受的时间内获得工作的 C 版本。

标签: python c compilation


【解决方案1】:

Python(至少是“标准”CPython 实现)从未真正编译为本机机器码;它编译成字节码,然后被解释。因此,实际上编译为机器代码的 C 函数将运行得更快;问题是它是否会产生相关的影响。那么您要解决的实际问题是什么?

【讨论】:

  • 为了迂腐,可以编译 Python - Jython、IronPython 和 PyPy(以及 x86 上的 Psyco)中的 JIT 编译,Cython 中的 AOT 编译(好吧,严格来说是另一种语言)和一些通过处于不同完成阶段的各种项目编写代码(例如 Shedskin。
  • 我要实现 levenberg marquardt 算法
  • @JohnJohnGa:嗯,你肯定知道 Python 实现永远不会快到实用吗?如果没有,请遵循有用的规则“让它运行,使其正确,使其快速 - 按此顺序”并在优化之前用 Python 编写它(例如,用 C 或 Cython 重写,尽管您可以轻松地获得 20 倍或更多)编码草率的 Python 函数)。
  • 好吧,a GPL version in C 已经存在,加上Python bindings。我希望这比原生 CPython 实现要快得多。
【解决方案2】:

如果我正确理解并重申了您的问题,您是在问,将 python 包装在 c 可执行文件上是否比纯 python 模块本身更快?答案是,它取决于可执行文件和您正在执行的任务类型。

  1. Python 中有一组使用 Python C-API 编写的模块。这些性能与包装 C 可执行文件相当
  2. 另一方面,包装 c 程序会比纯 python 更快,两者都使用理智的逻辑实现相同的功能。比较 difflib 的使用与通过 diff 包装子进程。

【讨论】:

    【解决方案3】:

    C 版本通常更快,但并非总是如此。加速的要点之一是 C 代码不必像 Python 那样动态查找值(Python 具有引用语义)。 Numpy 就是一个很好的例子。 Numpy arrays 是有类型的,数组中的所有值都具有相同的类型,并且内部存储在连续的内存块中。这是 numpy 快得多的主要原因,因为它跳过了 Python 必须执行的所有动态变量查找。如果算法在 Python 数据结构上运行,那么最高效的 C 算法实现可能会变得非常慢,其中每个值都必须动态查找。

    使用Cython 是自己实现这些东西并省去所有Python C-API 麻烦的好方法。

    【讨论】:

    • 同构数组实际上是动态成员查找成本的一个坏例子,因为完全不相关。成本来自必要的间接性,因为项目可以具有不同的大小(通常,与 Python 交互的 C 代码必须使用指向 PyObject 结构的指针)。尽管如此,还是对 Cython 竖起大拇指。
    • @delnan:带有数组的示例旨在与 Python 自己的列表形成对比,并且速度提升很大。要点是使用静态类型。顺便说一句,我实际上是从你给我的this question 的回答中了解到 Cython 的 :)。
    【解决方案4】:

    通常,用 C 编写的函数将比 Python 等效函数快得多。它也更难集成,因为它涉及:

    1. 编译 C 代码,#includes Python 标头并公开适当的包装器代码,以便可以从 Python 调用它;
    2. 链接到正确的 Python 库;
    3. 将生成的共享库部署到适当的位置,以便您的 Python 代码可以导入它。

    在尝试此操作之前,您需要非常确定收益大于成本,这意味着这应该只保留给代码的性能关键部分,而纯 Python 无法使其足够快。

    如果你真的需要走这条路,Boost.Python 可以让这项任务变得不那么痛苦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 2013-10-18
      • 2011-10-27
      • 1970-01-01
      • 2023-01-28
      • 2019-04-26
      • 2018-11-25
      相关资源
      最近更新 更多