当前位置: 首页 > 科技观察

Python调用C模块及性能分析

时间:2023-03-22 13:38:17 科技观察

一.c,ctypes和python的数据类型的对应关系ctypestypectypePythontypec_charchar1-characterstringc_wcharwchar_t1-characterunicodestringc_bytecharint/longc_ubyteunsignedcharint/longc_shortshortint/longc_ushortunsignedshortint/longc_intintint/longc_uintunsignedintint/longc_longlongint/longc_ulongunsignedlongint/longc_longlong__int64或longlongint/longc_ulonglongunsigned__int64或unsignedlonglongint/longc_floatfloatfloatc_doubledoublefloatc_char_pchar*(NULterminated)stringorNonec_wchar_pwchar_t*(NULterminated)unicodeorNonec_void_pvoid*int/longorNone2.操作int>>>fromctypesimport*>>>c=c_int(34)>>>cc_int(34)>>>c.value34>>>c.value=343>>>c.value3433.操作字符串>>>p=create_string_buffer(10)>>>p.raw'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'>>>p.value='fefefe'>>>p.raw'fefe\x00\x00\x00\x00\x00\x00'>>>p.value='fefefeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee,#string太长,错误的triceprackback(mostrecentCalllast),line1,inValueError:stringtoolong4.operationpointer>>>i=c_int(999)>>>pi=pointer(i)>>>pi<__main__.LP_c_intobjectat0x7f7be1983b00>>>>pi.valueTraceback(mostrecentcallast):File"",line1,inAttributeError:'LP_c_int'objecthasnoattribute'value'>>>pi.contentsc_int(999)>>>pi.contents=c_long(34343)>>>pi.contentsc_int(34343)通过pointer获取指向值的指针通过contents获取指针的值5.cstructure#定义一个c的结构体,包括两个成员变量x和y>>>classPOINT(Structure):..._fields_=[('x',c_int),('y',c_int)]...>>>point=POINT(2,4)>>>point<__main__.POINTobjectat0x7f7be1983b90>>>>point.x,point.y(2,4)>>>porint=POINT(y=2)>>>porint<__main__.POINTobjectat0x7f7be1983cb0>>>>point=POINT(y=2)>>>point.x,point.y(0,2)定义一个类型为POINT的数组>>>POINT_ARRAY=POINT*3>>>pa=POINT_ARRAY(POINT(2,3),POINT(2,4),POINT(2,5))>>>foriinpa:printpa.y...Traceback(mostrecentcallast):File"",line1,inAttributeError:'POINT_Array_3'objecthasnoattribute'y'>>>foriinpa:printi.y...3456。访问so文件1.创建一个c文件#includeinthello_world(){printf("HelloWorld\n");return0;}intmain(){hello_world();return0;}2.编译成动态链接库gcchello_world.c-fPIC-shared-ohello_world.so3.python调用库中的函数fromctypesimportcdllc_lib=cdll.LoadLibrary('./hello_world.so')c_lib.hello_world()2.测试两者的区别c和python的性能sum.cintsum(intnum){longsum=0;inti=0;for(i=1;i<=num;i++){sum=sum+i;};returnsum;}intmain(){printf("%d",sum(10));return0;}测试计划:计算1-100的和测试次数:100万次1.直接用c执行,通过linux的time命令记录执行timesum.c:#includeintsum(intnum){longsum=0;inti=0;for(i=1;i<=num;i++){sum=sum+i;};returnsum;}intmain(){inti;for(i=0;i<1000000;i++){sum(100);}return0;}测试结果示例:real1.16user1.13sys0.012。通过Python测试结果调用so文件和pythonsum_test.py:defsum_python(num):s=0foriinxrange(1,num+1):s+=ireturnsfromctypesimportcdllc_lib=cdll.LoadLibrary('./sum.so')defsum_c(num):returnc_lib.sum(num)deftest(num):importtimeitt1=timeit.Timer('c_lib.sum(%d)'%num,'from__main__importc_lib')t2=timeit.Timer('sum_python(%d)'%num,'from__main__importsum_python')print'c',t1.timeit(number=1000000)print'python',t2.timeit(number=1000000)if__name__=='__main__':exampleoftest(100)测试结果c1.02756714821python7.906728029253.erlang的测试结果刚学完erlang,我们来一起测试erlang的计算性能sum.erl:-module(sum).-export([sum/2,sum_test/2]).sum(0,Sum)->Sum;sum(Num,Sum)->sum(Num-1,Sum+Num).sum_test(Num,0)->0;sum_test(Num,Times)->sum(Num,0),sum_test(Num,Times-1).调用:定时器:tc(sum,sum_test,[100,1000000])。测试结果示例:{2418486,0}4、测试结果采用上述测试方法进行10次测试,去掉最大值和最小值,然后计算平均值,得到:单位:秒的运行求和使用的内存相对较小,但占用的CPU资源比比较原生的C是最快的,Python调用c会稍微慢一些,因为求和100的操作是c做的,执行100万次的逻辑是python做的,虽然erlang的性能更好比c稍微慢点,不过也不错,python的运行效率惨不忍睹。..

最新推荐
猜你喜欢