在Python中,为什么用C实现的模块比纯Python模块快,我该如何编写一个模块?

在Python中,为什么用C实现的模块比纯Python模块快,我该如何编写一个模块?,python,c,python-c-api,Python,C,Python C Api,python文档指出,cPickle比Pickle快的原因是前者是用C实现的。这到底意味着什么 我正在用Python制作一个高等数学模块,有些计算需要花费大量时间。这是否意味着如果我的程序是用C语言实现的,它可以变得更快 我希望从其他Python程序导入此模块,就像导入cPickle一样 您能解释一下如何用C实现Python模块吗?您可以编写快速C代码,然后在Python脚本中使用它,这样您的程序会运行得更快。[1] 一个例子是Numpy,用C()编写 由于速度的原因,典型的用法是用C实现瓶颈

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

我正在用Python制作一个高等数学模块,有些计算需要花费大量时间。这是否意味着如果我的程序是用C语言实现的,它可以变得更快

我希望从其他Python程序导入此模块,就像导入cPickle一样


您能解释一下如何用C实现Python模块吗?

您可以编写快速C代码,然后在Python脚本中使用它,这样您的程序会运行得更快。[1]

一个例子是Numpy,用C()编写

由于速度的原因,典型的用法是用C实现瓶颈(当然也可以使用C编写的库),其余的代码使用python

[1] 顺便说一下,这就是为什么cPickle比pickle快的原因

编辑:

看看Pyrex:

Pyrex是一种特殊的语言 专为编写Python扩展而设计 模块。它的设计是为了连接 好的,高水平的, 易于使用的Python世界和 混乱、低级的C世界


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

如前所述,numpy非常适合向量计算。(可能会更好,但有评论说,这比你在没有实际工作的情况下可以写的任何东西都要好,这绝对是真的。)

不过,并不是所有内容都可以轻松矢量化,因此,如果您确实拥有具有大量函数调用的紧密内部循环(比如一个高度递归的算法),那么您仍然有两个选项:可能最流行的是,它允许您使用带注释的Python编写模块和函数,并在需要时获得类似C的速度


或者,您的时间都被计算特征值或求逆矩阵、计算特殊函数或划分非常大的整数的库调用所支配——顺便说一句,如果您所做的工作更像是数学运算,而不是纯粹的运算——在这种情况下,在Python中花费的时间甚至可能无关紧要。这一切都取决于你所做的数字类型的细节。

除了前面提到的Pyrex/Cython之外,你还有其他选择:

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

:更快的Python,带有JIT编译器。您可以简单地在其上运行代码,而不是在CPython上运行代码。现在只支持Python 2.5,不久将支持Python 2.7。可以在数学繁重的代码上提供巨大的加速。要安装并运行它(假定为Linux 32位):

:允许您进行编辑


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

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

如果使用C编写相同的函数,遵循C/Python API使其在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>
>>map.func\u代码
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“内置函数”或“方法”对象没有“函数代码”属性
>>>def mymap():传递
... 
>>>mymap.func_代码
<0xcfb5b0处的代码对象mymap,文件“stdin”,第1行>
要了解如何为python编写C代码,请遵循官方网站上的指南


无论如何,如果您只是简单地进行N维数组计算,numpy应该足够了。

+1您应该将核心计算的纯C实现与使用numpy完成繁重工作的Python实现进行基准测试。Numpy实现很有可能具有竞争力。Numpy为+1。如果Numpy做了你想做的事情,它很有可能会比你在不花大量时间优化代码的情况下所能写的任何东西都要快。我正在做一些我在网上找不到的不同的事情,不管怎样,这很有帮助,谢谢!
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"
>>> 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>