众所周知,python是一种解释性语言。虽然使用了虚拟机,宏代码生成inline代码的方式来进行加速,但是由于其天生的GIL锁,动态等天生劣势,导致代码执行效率慢于传统静态语言。目前的大部分思路都是大部分功能性代码使用python。关键性能部分使用c来写扩展。下面就逐一来测试下各个方式的性能及优劣。
- python的c扩展
- cython
- ctypes调用so库
- matx
首先前四章分别介绍下使用方法。本章主要介绍c扩展的方法。
1.创建my_extend.c文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Python.h>
//具体实现函数。实现循环次数累加并返回
int count(int n){
int ans=0;
for(int i=0;i<=n;i++){
ans= ans + 1;
}
return ans;
}
//python的函数封装,解析python参数,将参数转为c类型并调用实际的c函数
static PyObject *Extest_count(PyObject *self,PyObject *args){
int num;
if(!(PyArg_ParseTuple(args,"i",&num))){
return NULL;
}
return (PyObject*)Py_BuildValue("i",count(num));
}
//为每个模块增加PyMethodDef ModuleMethods[]数组
static PyMethodDef ExtestMethods[] = {
{"count",Extest_count,METH_VARARGS},
{NULL,NULL},
};
//模块定义
static struct PyModuleDef ExtestModule = {
PyModuleDef_HEAD_INIT,
"Extest",
NULL,
-1,
ExtestMethods
};
//模块注册函数PyInit_Extest为函数名,PyInit_为指定前缀,Extest为模块名称
void PyInit_Extest(){
PyModule_Create(&ExtestModule);
}
编写编译文件,创建setup.py文件
from distutils.core import setup,Extension
MOD = 'Extest' # 模块名
cpp_args = ["-O2"] # 由于matx默认使用o2级别优化。所以所有的测试都默认使用o2级别优化
setup(
name=MOD,
ext_modules=[Extension(MOD,sources=['my_extend.c'], extra_compile_args=cpp_args)],
) #源文件名
执行python3 setup.py build
将build文件夹下lib.操作系统.架构-python版本文件夹下的so库文件拷贝到测试目录。
编写test.py文件
from Extest import count
print(count(9999))
执行文件即可