python c 扩展 ctype 以及 效率对比
2013-11-01 22:34
483 查看
python开发效率高,第三方库资源丰富,而且可以用C/C++扩展。(基于python官方文档)
今天研究了用C来写python的扩展,用的是2.x版本的,刚开始还弄错了,看的是3.x版本的文档,浪费了不少时间。
其实用c/c++写python的扩展,有至少四种方法:
1、原生python c api
2、ctypes
3、boost.python
4、swig
后面两种需要额外下载安装boost.python 或者 swig,更加麻烦,所以只是实验了前两种。
首先将用C/C++ 编写python扩展吧;
我是在widows下,用的 vs2010 express,新建一个win32 DLL工程
然后在源码里面增加下面代码,主要实现了add方法,实现返回累加值,比如输入100,返回 1加到100
注意:需要将python安装目录下的 include(头文件) 和 lib 文件夹(库文件) 加入工程目录,我用的python (x,y) 所以还加了 libs目录
最后可以编译了,编译成一个 *. dll 文件,改成 *.pyd 然后copy到 python 的lib文件夹下,这样就可以用了,
比如我这个工程叫做spam,编译成spam.dll,重命名为spam.pyd
以上,可以看出来用ctype写扩展,主要是三部分:
1.函数主体,需要实现变量 从python到 c,然后从 c到python的转换
2.定义方法,static PyMethodDef ,确定python中方法与c中方法的映射关系
3,初始化模块,
以上步骤完成后,可以开始测试一下c扩展作用有多大了。。
重启python ,
可以看到模块有一个方法叫做add
然后我们开始测试python 和c扩展模块的速度差别了:
用python和c返回1到 10000000 的累加和,c里面要用long long 存,不然会溢出哦~
各自计算10遍,然后算平均时间:
上面的方法太复杂了,用Ctype更简单,直接写一个C++的DLL,用Ctypes调用就ok了
windows下面注意在函数前加_declspec(dllexport),表示一个导出的函数
然后在python 中调用,这里我生成的dll叫做TT.dll,把它拷贝到了python代码的所在目录
it works
然后比较一下性能吧
运行结果:
今天研究了用C来写python的扩展,用的是2.x版本的,刚开始还弄错了,看的是3.x版本的文档,浪费了不少时间。
其实用c/c++写python的扩展,有至少四种方法:
1、原生python c api
2、ctypes
3、boost.python
4、swig
后面两种需要额外下载安装boost.python 或者 swig,更加麻烦,所以只是实验了前两种。
首先将用C/C++ 编写python扩展吧;
我是在widows下,用的 vs2010 express,新建一个win32 DLL工程
然后在源码里面增加下面代码,主要实现了add方法,实现返回累加值,比如输入100,返回 1加到100
注意:需要将python安装目录下的 include(头文件) 和 lib 文件夹(库文件) 加入工程目录,我用的python (x,y) 所以还加了 libs目录
最后可以编译了,编译成一个 *. dll 文件,改成 *.pyd 然后copy到 python 的lib文件夹下,这样就可以用了,
比如我这个工程叫做spam,编译成spam.dll,重命名为spam.pyd
#include <Python.h> static PyObject *SpamError; static PyObject * spam_add(PyObject * self,PyObject *args) { long a; //将python中传入的变量转化成C中的变量 if(!PyArg_ParseTuple(args,"l",&a)) return NULL; long long tmp=0; for(long i = 1;i<=a;i++) tmp +=i; //将C中的变量转化成python中的变量 return Py_BuildValue("L",tmp); } //方法定义 static PyMethodDef SpamMethods[] = { //每个方法都有四个属性 //分别为 1、python中方法名 2、c中名称 //3、应该就是传入的参数 //4、方法描述 {"add",spam_add,METH_VARARGS, "Return the cumulative value "}, //这个是必须加的,应该都一样吧 {NULL, NULL, 0, NULL} /* Sentinel */ }; //初始化模块 PyMODINIT_FUNC initspam(void) { PyObject *m; //参数:模块名称 ,方法数组 m = Py_InitModule("spam", SpamMethods); if (m == NULL) return; //异常处理 SpamError = PyErr_NewException("spam.error", NULL, NULL); Py_INCREF(SpamError); PyModule_AddObject(m, "error", SpamError); }
以上,可以看出来用ctype写扩展,主要是三部分:
1.函数主体,需要实现变量 从python到 c,然后从 c到python的转换
2.定义方法,static PyMethodDef ,确定python中方法与c中方法的映射关系
3,初始化模块,
以上步骤完成后,可以开始测试一下c扩展作用有多大了。。
重启python ,
import spam dir(spam)
可以看到模块有一个方法叫做add
然后我们开始测试python 和c扩展模块的速度差别了:
用python和c返回1到 10000000 的累加和,c里面要用long long 存,不然会溢出哦~
各自计算10遍,然后算平均时间:
# -*- coding: utf-8 -*- """ Created on Thu Oct 31 20:59:38 2013 @author: peter """ import time import spam start = time.clock() for i in xrange(10): spam.add(10000000) t1 = (time.clock()-start)/10 print "c cost time:",t1 start = time.clock() for j in xrange(10): tmp = 0 for i in xrange(1,10000001): tmp +=i t2 = (time.clock()-start)/10 print "python cost time:",t2 print "c is %f times faster "%(t2/t1)
c cost time: 0.0104223142169 python cost time: 2.59412283937 c is 248.900847 times faster
上面的方法太复杂了,用Ctype更简单,直接写一个C++的DLL,用Ctypes调用就ok了
windows下面注意在函数前加_declspec(dllexport),表示一个导出的函数
extern "C" { _declspec(dllexport) long long add(long x) { long long y = 0; for(long a = 1;a<=x;a++) y+=a; return y; } }
然后在python 中调用,这里我生成的dll叫做TT.dll,把它拷贝到了python代码的所在目录
import ctypes test =ctypes.CDLL('TT.dll'); print test.add(100)
it works
然后比较一下性能吧
# -*- coding: utf-8 -*- """ Created on Thu Oct 31 20:59:38 2013 @author: peter """ import time import spam import ctypes # test c module start = time.clock() for i in xrange(10): spam.add(10000000) t1 = (time.clock()-start)/10 print "c cost time:",t1 # test python start = time.clock() for j in xrange(10): tmp = 0 for i in xrange(1,10000001): tmp +=i t2 = (time.clock()-start)/10 print "python cost time:",t2 # test ctype test =ctypes.CDLL('TT.dll'); start = time.clock() for i in xrange(10): test.add(10000000) t3 = (time.clock()-start)/10 print "ctype cost time:",t3 start = time.clock() print "c is %f times faster "%(t2/t1) print "ctype is %f times faster "%(t2/t3)
运行结果:
c cost time: 0.0107829747003 python cost time: 2.6450129228 ctype cost time: 0.0125509386257 c is 245.295292 times faster ctype is 210.742240 times faster
相关文章推荐
- python访问mysql
- python访问mysql
- Python 用POP接收邮件
- Python 用IMAP接收邮件
- Python 用SMTP发送邮件
- Python Ogre Blender(转载)
- 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(中)
- 教你用python写游戏~
- 一步一步学编程之Python(六)
- <www.pythonchallenge.com>----Lv2
- python 共享引用
- Python源码学习七 .py文件的解释
- generate IFC profile with python
- 循环显示CNFG status with python
- python 实现日期加1天或减少一天
- Python语言的创始人解释为什么Python数组的索引从0开始
- python学习十:copy模块、collections模块中的defaultdict、pydiction完成在vim中tab补全
- 将python 添加进64位win7 的注册表
- 关于python的str()和repr()函数
- python实现下载pop3邮件保存到本地