Python与C/C++混合编程的应用(3)

使用一个长度为100内容固定的数组,反复排序10000次(每次排序后,再把数组恢复成原始序列),记录执行时间:
在相同的机器上多次执行,Python版执行时间是10.3s左右,而c语言版本(未使用任何优化编译参数)执行时间只有0.29s左右。相比之下python的性能的确差很多(主要是python中list的操作跟c的数组相比,效率差非常多),但python中很多扩展都是c语言写的,目的就是为了提升效率,python用于数据分析的numpy库就拥有不错的性能。下个实验就验证,如果python使用c语言版本的冒泡排序扩展库,性能会提升多少。

2)实验二 python语言使用ctypes方式调用
这里直接使用c_int来定义了数组对象,这也节省了调用时数据类型转换的开销:

import time
from ctypes import *
IntArray100 = c_int * 100
arr = IntArray100(87,23,41, 3, 2, 9,10,23,0,21,5,15,93, 6,19,24,18,56,11,80,34, 5,98,33,11,25,99,44,33,78,
      52,31,77, 5,22,47,87,67,46,83, 89,72,34,69, 4,67,97,83,23,47, 69, 8, 9,90,20,58,20,13,61,99,7,22,55,11,30,56,87,29,92,67,
      99,16,14,51,66,88,24,31,23,42,76,37,82,10, 8, 9, 2,17,84,32,66,77,32,17, 5,68,86,22, 1, 0)
... ...
if __name__ == "__main__":
    libbubble = CDLL('libbubble.so')
    time1 = time.time()
    for i in xrange(100000):
        libbubble.initArr(arr1,arr,100)
        libbubble.bubble(arr1,100)
    time2 = time.time()
    print time2 - time1

再次执行:
为了减少误差,把循环增加到10万次,结果c原生程序使用优化参数编译后用时0.65s左右。python使用c扩展后(相同编译参数)执行仅需2.3s左右。
3)实验三 在c语言中使用PyObject处理入参
这种方式是在python中依然使用list装入待排序数列,在c函数中把list赋值给数组,再进行排序,排好序后,再对原始list赋值。循环排序10万次,执行用时1.0s左右。
4) 实验四 使用swig来包装c方法
在接口文件中声明%array_class(int,intArray);然后在Python中使用initArray来作为数组,同样修改成10万次排序。python版本的程序(相同编译参数)执行仅需0.7s左右,比c原生程序慢大概7%。

结论

1.python 的list效率非常低,在高性能场景下避免对list大量循环、取值、赋值操作。如需要最好使用ctype中的数组,或者是用c语言来实现。
2.应该把耗时的cpu密集型的逻辑交给c/c++实现,python使用扩展即可。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8c527a84b53d046fba64ac8b4fe57972.html