一、我们以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)
- 将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);
}
- 在linux环境下fibonacci.c编译成动态链接库fibonacci.so:
编译命令为:
gcc fibonacci.c -fPIC -shared -o fibonacci.so - Python文件中调用动态链接库a.so,在Windows平台下,最终调用的是Windows API中LoadLibrary函数和GetProcAddress函数,在Linux和Mac OS X平台下,最终调用的是Posix标准中的dlopen和dlsym函数。ctypes库内部完成PyObject* 和C types之间的类型映射,使用时只需设置调用参数和返回值的转换类型即可。
- 利用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的加速