[在Python中,为什么用C实现的模块比纯Python模块要快,我该怎么写?

问题描述 投票:10回答:4

python文档指出,cPickle比Pickle更快的原因是,前者是用C实现的。这到底是什么意思?

我正在为Python中的高级数学制作模块,并且某些计算需要大量时间。这是否意味着如果我的程序是用C语言实现的,可以使其速度更快?

我希望从其他Python程序中导入此模块,就像我可以导入cPickle的方式。

您能解释一下如何在C语言中实现Python模块吗?

python c python-c-api
4个回答
17
投票

您可以编写快速的C代码,然后在python脚本中使用它,因此您的程序将运行得更快。[1]http://docs.python.org/extending/index.html#extending-index

一个例子是用C(https://numpy.org/)编写的Numpy

由于速度的原因,典型的用法是在C中实现瓶颈(或者当然要使用C编写的库;),并在剩余的代码中使用python]

[1],这就是为什么cPickle比pickle更快的原因

编辑:

看看派热克斯(Pyrex):http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/About.html

'Pyrex是一种特殊的语言设计用于编写Python扩展模块。它旨在桥接好的,高级的,易于使用的Python和凌乱的C语言低级世界。'

这不是“官方”方式,但可能有用


10
投票

如上所述,numpy非常适合矢量计算。 (这可能会更好,但是绝对比没有实际工作就可以写的任何东西还更好的说法是正确的。)

但是,并非所有内容都可以轻松地向量化,因此,如果您确实有很多函数调用的紧密内部循环(例如,大量递归算法),那么您仍然可以选择两种方法:最流行的是Cython,它允许您可以使用带注释的Python编写模块和函数,并在需要时获得类似于C的速度。

或者也许您的时间全部由库调用来控制,以计算特征值或求矩阵求逆,或者评估特殊函数或除以非常大的整数-顺便说一句,Sage项目处理得很好,如果您要这样做比纯粹的运算更加数学化-在这种情况下,花费在Python上的时间甚至可能无关紧要。这完全取决于您正在执行的数字类型的详细信息。


9
投票

[当您使用python编写函数时,将创建一个新的函数对象,该函数代码将被解析和字节编译[并保存在“ func_code”属性中],因此,当您调用该函数时,解释器将读取其字节码并执行它。

如果您使用C / Python API使用C编写相同的函数以使其在python中可用,则解释器将创建函数对象,但是此函数将没有字节码。当解释器找到对该函数的调用时,它将调用真正的C函数,因此它以“机器”速度而不是“ python-机器”速度执行。

您可以验证用C编写的此检查功能:

>>> map.func_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute 'func_code'
>>> def mymap():pass
... 
>>> mymap.func_code
<code object mymap at 0xcfb5b0, file "<stdin>", line 1>

要了解如何编写适用于python的C代码,请遵循官方网站上的指南。

无论如何,如果您只是在进行N维数组计算,那么numpy就足够了。


7
投票

除了Pyrex / Cython,已经提到,您还有其他选择:

Shed Skin:将Python(的受限子集)翻译成C ++。可以自动为您生成扩展名。您将创建一个扩展来执行此操作(假设使用Linux):

wget http://shedskin.googlecode.com/files/shedskin-0.7.tgz
tar -xzf shedskin-0.7.tgz
# On your code folder:
PYTHONPATH=/path/to/shedskin-0.7 python shedskin -e yourmodule.py
# The above generates a Makefile and a yourmodule.h/.cpp pair
make
# Now you can "import yourmodule" from Python and check it's from the .so by "print yourmodule.__file__

PyPy:使用JIT编译器的更快Python。您可以简单地在其上运行代码,而不是CPython。现在仅支持Python 2.5,很快将支持2.7。可以大大提高数学上繁重的代码的速度。要安装并运行它(假设Linux为32位):

wget http://pypy.org/download/pypy-1.4.1-linux.tar.bz2
tar -xjf pypy-1.4.1-linux.tar.bz2
sudo ln -s /path/to/pypy-1.4.1-linux/bin/pypy /usr/local/bin
# Then, instead of "python yourprogram.py" you'll just run "pypy yourprogram.py"

[Weave:允许您编译write C inline

编辑:如果您希望我们为您和基准测试运行这些工具,只需发布​​您的代码;)

© www.soinside.com 2019 - 2024. All rights reserved.