最近做性能压测,接口都是文件协议,需要用Python生成大数据量的交易文件,涉及到一个生成11位不重复的账号,考虑用系统毫秒数加序列来生成,但是光系统毫秒数都已经13位了,位数不够用,想到可以用62进制来压缩位数,结果用Python的写法,调用1000W次,需要68秒,就想到了可以用C来进行扩展。
首先在Clion中新建一个C Library ,type选shared,standard选C99
然后在CMakeLists.txt文件中加入python头文件的路径:
include_directories(/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m)
在library.c文件中写入代码:
#include <Python.h>
/*引用python的头文件*/
char * zip(long long dec_number, char *result) {
char* r = result;
char baseList[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char tmp[] = "00000000000";
int i = 0;
while (i < 11) {
long long x, y;
x = dec_number /62;
y = dec_number % 62;
if (x <1) {
tmp[10-i] = baseList[dec_number];
i ++;
break;
} else {
tmp[10-i] = baseList[y];
dec_number = x;
i ++;
}
}
for (int j = 0; j < i ; ++j) {
*r++ = tmp[11-i+j];
}
*r++ = '\0';
return result;
}
int getNumber(char p) {
if (p >= 97 && p <= 122) {
return p - 87;
} else if (p >= 65 && p <= 90) {
return p - 29;
} else
return p - 48;
}
long long myPow(int x, int y) {
long long result = x;
if (y == 0) {
result = 1;
}
else {
for (int i = 0; i < y-1; ++i) {
result *= x ;
}
}
return result;
}
long long unzip(char *number_62) {
long long result = 0;
int number_len = strlen(number_62);
for (int i = 0; i < number_len; ++i) {
result += getNumber(number_62[i]) * myPow(62, number_len-i-1);
}
return result;
}
static PyObject * zipString_zip(PyObject *self, PyObject *args){
/*参数转换,把Python传入的参数转换成c的参数类型*/
long long num;
if(!(PyArg_ParseTuple(args, "L", &num))){
return NULL;
}
char result[11];
result = zip(num, result);
//把c函数的返回值转换成Python的数据类型
return Py_BuildValue("s", result);
}
static PyObject * zipString_unzip(PyObject *self, PyObject *args){
char *s;
if(!(PyArg_ParseTuple(args, "z", &s))){
return NULL;
}
long long p = unzip(s);
return Py_BuildValue("L", p);
}
//将函数添加到Python模块中,以便可以在Python中导入
static PyMethodDef zipStringMethods[]={
{"zip", zipString_zip, METH_VARARGS},
{"unzip", zipString_unzip, METH_VARARGS},
{NULL, NULL},
};
static struct PyModuleDef zipStringModule = {
PyModuleDef_HEAD_INIT,
"zipString",
NULL,
-1,
zipStringMethods
};
//创建模块
void PyInit_zipString(){
PyModule_Create(& zipStringModule);
}
编写setup.py文件,用于打包和安装:
from distutils.core import setup, Extension
MOD = 'zipString'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['library.c'], extra_compile_args=["-std=c99"])])
最后在终端中输入:
cd ~/CLionProjects/zipString/
sudo python3 setup.py build
sudo python3 setup.py install
然后就可以愉快的在Python中调用啦:
import zipString
print(zipString.zip(1546335593004))
print(zipString.unzip("rdTsyNm"))
控制台输出:
现在再在python中调用这个压缩1000W次,只需要3秒钟啦