将Python程序转换为C/C++代码?

Cra*_*ine 133 c c++ python code-generation

是否可以将Python程序转换为C/C++?

我需要实现几个算法,我不知道,如果性能差距大到足以证明所有的痛苦在C/C++(这我不擅长)做的时候我会去.我考虑过编写一个简单的算法,并针对这样一个转换后的解决方案进 如果仅这一点明显快于Python版本,那么除了在C/C++中做这件事之外我别无选择.

S.L*_*ott 131

如果C变体需要x小时,那么我会花时间让算法运行更长/更久

"投资"在这里不是正确的词.

  1. 在Python中构建一个工作实现.在完成C版本之前,你将完成这么久.

  2. 使用Python分析器测量性能.解决您发现的任何问题.根据需要更改数据结构和算法,以便真正做到这一点.在C完成第一个版本之前,你将完成这么久.

  3. 如果它仍然太慢,请手动将精心设计和精心构造的Python转换为C.

    由于后见之明的工作方式,从现有的Python(使用现有的单元测试和现有的分析数据)执行第二个版本仍然比尝试从头开始执行C代码更快.

这句话很重要.

汤普森对第一次望远镜制造商的规则
制作一个四英寸镜子然后一个六英寸镜子比制作一个六英寸镜子更快.

Bill McKeenan
Wang Institute

  • @Audrius Meskauskas,它没有,它消除了它,使得这个问题的前提变得不必要。换句话说,它解释了如何把事情做得比所要求的更好,而不是所要求的。 (9认同)
  • 不管得分很高,我都看不出这是如何回答这个问题的。 (7认同)
  • 至于我,我会单独为最后的引用投赞成票。当推断到 C 语言编程时,这是非常有洞察力的。我正在 C 语言中实现 fast_malloc()。我花了 4 周时间完成一个我认为需要几天时间的项目。我的大部分时间都花在了代码的支持结构上,而不是代码本身。如果建造一个棚子是目标,我的大部分精力都花在建造钉子、锤子、锯子和制造油漆的化学品上,这样我就可以制作混合油漆的罐子和油漆也粘一下,然后涂漆。 (5认同)

Len*_*bro 103

是.看看Cython.它就是这样:将Python转换为C以获得加速.

  • 当然,除非你添加一堆`cdef`声明,然后引入静态类型(否则你只是玩弄不透明的`PyObject*`东西),这将无法为你节省任何东西.并且它永远不会像普通的C那样快,因为它通常与Python接口(100%或更多?仅适用于大部分时间都不与Python接口的普通数字代码!).但除此之外,是的,它可以让你获得相当快的加速. (5认同)
  • @delnan:事实上,它确实为你节省了一些东西.编译后,大多数纯Python代码会更快.但是,是的,使用cdefs和静态类型,你真的开始看到差异.在Python中使用C的所有情况下都可以与Python接口. (5认同)

eph*_*ent 27

Shed Skin是"一个(受限制的)Python-to-C++编译器".

  • "Shed Skin"的一个优点是*类型推断*:如果可以从程序流中猜测变量类型,则可以避免动态类型检查.这通常会导致更短的C++代码,实际上可以读取并编译为更快的程序. (3认同)

小智 14

刚刚在黑客新闻中遇到了这个新工具.

从他们的页面 - "Nuitka是Python解释器的一个很好的替代品,并编译CPython 2.6,2.7,3.2和3.3提供的每个构造.它将Python转换为C++程序,然后使用"libpython"以与CPython以非常兼容的方式完成."

  • Nuitka 很棒,但创建的 C/C++ 代码是使用 PyObject 绑定到 CPython-C 代码实现。它不会生成惯用的 C 代码。 (3认同)
  • 这个项目比其他类似的选项成熟得多。有趣的是,它在 OSX 上创建带有“.exe”扩展名的二进制文件,尽管它是一个完全正常的 OSX Mach-O 可执行文件。看起来它可能是 `pyinstaller`、`py2exe`、`py2app` 等的一个很好的替代品。不过,正确设置 `--recurse-***` 标志很重要。 (2认同)

jac*_*der 10

我知道这是一个较旧的线程,但我想提供我认为有用的信息。

我个人使用 PyPy,它使用 pip 非常容易安装。我交替使用 Python/PyPy 解释器,您根本不需要更改代码,我发现它比标准 Python 解释器(Python 2x 或 3x)快大约 40 倍。我使用 pyCharm 社区版来管理我的代码,我喜欢它。

我喜欢用 python 编写代码,因为我认为它可以让你更专注于任务而不是语言,这对我来说是一个巨大的优势。如果你需要它更快,你总是可以编译为适用于 Windows、Linux 或 Mac 的二进制文件(不是直接的,但可以使用其他工具)。根据我的经验,编译时我的速度比 PyPy 快 3.5 倍,这意味着比 Python 快 140 倍。PyPy 可用于 Python 3x 和 2x 代码,如果您使用像 PyCharm 这样的 IDE,您可以非常轻松地在 PyPy、Cython 和 Python 之间进行交换(尽管需要一些初始学习和设置)。

有些人可能会在这个问题上与我争论,但我发现 PyPy 比 Cython 更快。不过两者都是不错的选择。

编辑:我想再做一个关于编译的快速说明:当你编译时,生成的二进制文件比你的 python 脚本大得多,因为它把所有的依赖项都构建到其中,等等。但是你会得到一些明显的好处:速度!,现在该应用程序可以在没有 Python 或库的任何机器上运行(取决于你编译的操作系统,如果不是全部。哈哈),它也会混淆你的代码,并且在技术上已经准备好(在一定程度上)“生产”。一些编译器还生成 C 代码,我没有真正看过或看到它是否有用或只是胡言乱语。祝你好运。

希望有帮助。

  • 我知道这是一个较旧的评论,但谢谢! (2认同)
  • 我还发现 PyPy 比 Cython 运行得更快。在一项测试中,我实际上发现 PyPy 与该程序的 C++ 版本(插入排序)的速度相同。 (2认同)

ash*_*ley 5

http://code.google.com/p/py2c/看起来有可能 - 他们还在他们的网站上提到:Cython、Shedskin 和 RPython 并确认他们正在将 Python 代码转换为比 C 快得多的纯 C/C++ /C++ 充满了 Python API 调用。注意:我还没有尝试过,但我要去..

  • 看来Py2C仍然是一个未完成的项目。已经好几年没有更新了,所以可能已经失效了。 (2认同)

pau*_*ier 5

我意识到缺少关于一个全新解决方案的答案。如果代码中使用了 Numpy,我建议尝试 Pythran:

http://pythran.readthedocs.io/

对于我尝试过的功能,Pythran 给出了非常好的结果。生成的函数与编写的 Fortran 代码一样快(或仅稍微慢一点),并且比(相当优化的)Cython 解决方案快一点。

与 Cython 相比的优势在于,您只需在针对 Numpy 优化的 Python 函数上使用 Pythran,这意味着您不必扩展循环并为循环中的所有变量添加类型。Pythran 花时间分析代码,以便理解对numpy.ndarray.

与 Numba 或其他基于即时编译的项目相比,这也是一个巨大的优势(据我所知),您必须扩展循环才能真正高效。然后只使用 CPython 和 Numpy 的循环代码变得非常低效......

Pythran 的一个缺点:没有类!不过既然只需要编译真正需要优化的函数,那就不是很烦了。

另一点:Pythran 很好地(并且非常容易地)支持 OpenMP 并行性。但我认为不支持 mpi4py ......


boa*_*der 5

另一个选择 - 除了Shed Skin之外转换为C++ - 是Pythran.

引用Micha Gorelick和Ian Ozsvald的High Performance Python:

Pythran是Python的一个Python-to-C++编译器,包含部分numpy支持.它的行为有点像Numba和Cython - 你注释了一个函数的参数,然后它接管了进一步的类型注释和代码特化.它利用了矢量化的可能性和基于OpenMP的并行化可能性.它仅使用Python 2.7运行.

Pythran的一个非常有趣的特性是它将尝试自动发现并行化机会(例如,如果你正在使用a map),并将其转换为并行代码而无需你的额外努力.您还可以使用pragma omp >指令指定并行部分; 在这方面,它与Cython的OpenMP支持非常相似.

在幕后,Pythran将采用普通的Python和numpy代码,并尝试将它们积极地编译成非常快的C++ - 甚至比Cython的结果更快.

你应该注意到这个项目很年轻,你可能会遇到错误; 你还应该注意开发团队非常友好,并且会在几个小时内修复bug.

  • 请注意,“在 0.9.5(包含)之前,Pythran 支持 Python 3 和 Python 2.7。现在仅支持 Python 3。” (3认同)