Ctypes模块实现python加速运行

一、我们以Fibonacci数列的例子来看看,python的运行时间

def fibonacci(n):
    if n <= 2:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)


begin = time.time()
print(fibonacci(40))
over = time.time()
print(over - begin)

Linux环境运行的时间为16.93秒:(window下会更长)
在这里插入图片描述
二、我们来介绍ctypes模块
Python内建ctypes库使用了各个平台动态加载动态链接库的方法,并在Python源生代码基础上通过类型映射方式将Python与二进制动态链接库相关联,实现Python与C语言的混合编程,可以很方便地调用C语言动态链接库中的函数。(ctypes源码路径:/Modules/_ctypes/_ctypes.c、/Modules/_ctypes/callproc.c)

  1. 将C编写的递归函数存为fibonacci.c,不需要对C函数经过Python接口封装
#include <stdio.h>
#include <stdlib.h>

int fibonacci(int n)
{
    if(n<=2)return 1;
    return fibonacci(n-1)+fibonacci(n-2);
}
  1. 在linux环境下fibonacci.c编译成动态链接库fibonacci.so:
    编译命令为:
    gcc fibonacci.c -fPIC -shared -o fibonacci.so在这里插入图片描述
  2. Python文件中调用动态链接库a.so,在Windows平台下,最终调用的是Windows API中LoadLibrary函数和GetProcAddress函数,在Linux和Mac OS X平台下,最终调用的是Posix标准中的dlopen和dlsym函数。ctypes库内部完成PyObject* 和C types之间的类型映射,使用时只需设置调用参数和返回值的转换类型即可。
  3. 利用fibonacci.so来求fibonacci数列后的python代码
import time
from ctypes import cdll

libb = cdll.LoadLibrary('./fibonacci.so')


def fibonacci_c(n):
    return libb.fibonacci(n)


begin = time.time()
print(fibonacci_c(40))
over = time.time()
print(over-begin)

运行结果如下,利用动态链接库的形式计算第40个Fibonacci数列的值,只用了0.47秒:
在这里插入图片描述
对比两次的运行结果:
直接用python代码来编写和利用动态链接库的形式,时间提高了差不多提高了35倍
三、当然除了利用ctypes模块结合动态库的形式提速,还可以利用Python中扩展C语言加快执行速度的实现python的加速

猜你喜欢

转载自blog.csdn.net/mingtiannihaoabc/article/details/103109370