首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python笔记:外部c函数调用

Python笔记:外部c函数调用

作者头像
codename_cys
发布于 2021-03-25 15:50:43
发布于 2021-03-25 15:50:43
2.5K0
举报
文章被收录于专栏:我的充电站我的充电站

序言

前些时候,一个朋友突然问我:python做计算实在是太慢了,有什么办法可以加速python的运算吗?我说:简单啊,你直接调用外部c函数就行了,我印象中cython可以直接实现的。闻言,我那个朋友喜出望外,遂言:太好了,那你给我写个demo呗。。。

emmmm。。。

好吧,我承认我之前事实上只是知道可以这么做,真的要说实现。。。

唉,自己挖的坑,流着泪也要把它填平了。于是,趁着周末两天,我网上找了一些demo,然后自己实现了几种python调用外部c函数的实现方式。

不要问我为啥今天才发出来,问就是打字慢。

下面,话不多说,上干货!

1. ctypes实现

c_types实现大约是最简单的外部c函数实现方法了,你只需要准备写好你的C函数实现,然后编译,最后调用就行了,无需任何中间文件,一切都是如此简单。

下面,我们以a到b的连续求和函数作为例子来进行说明:

完事,收工,一切都是如此顺利!

2. cython实现

较之ctypes实现方法,cython方法会更加复杂一点,它不需要依赖于ctypes库,而是直接将c代码转译为python底层c实现中可读的代码,而后将这一部分封装为一个动态链接库。

因此,在这种情况下,我们完全可以将这个生成的动态链接库当成一个普通的python包来进行调用,其执行效率上也会优于ctypes方式的调用。

下面,我们来考察其具体实现。

由是,cython方法搞定收工!

3. c extension实现

注意到,cython方式构建动态链接库过程中,会调用cythonize函数,而这个函数会先生成一个.c中间文件,而这个中间文件即为我们的动态链接库中真实包含的c函数代码实现。

事实上,后续的setup函数就是针对这个.c中间文件进行编译并构建为动态链接库。

因此,我们可以绕过cythonize函数,直接自己来构建这个.c文件,然后进行动态链接库的构建。

而这,就是c extension方法的主要思路。

同样的,给出其操作流程如下:

综上,c extension方法搞定!

4. swig实现

swig也是常用的python调用外部c函数的实现方法之一,其核心与上述cython完全相似,唯一的区别点在于,cython方法使用cython库来进行代码转义,而这里使用swig进行代码转义。。。

我们给出其操作流程如下:

至此,swig方法搞定!

5. 效果测试 & 结论

现在,我们来比较一下上述各个方法调用外部c函数的性能。

我们重复执行10^7计算1到100的连续求和,得到各个方法的耗时如下:

方法

耗时

python

~50s

ctypes

~7s

cython

1.88s

c extension

2.76s

swig

2.41s

结论:

  1. 上述4种方式实现c函数外部调用确实能给python带来极大的性能提升;
  2. 就实现方式来说,ctypes是最容易实现的,但是相对的,其执行效率也是4种方法中最慢的;
  3. c extension、cython以及swig三种实现方法本质上来说是同一种实现方法,其外部c函数调用的执行速度上没有量级上的差异,但是从其实际的效果来看,cython方式相对而言操作更为简单,其效率也是最高的。

参考文献

[1] 在python里调用C函数的三种方式 [2] python调用c和c++库(直接调用和使用swig) [3] SWIG and Python

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/06/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 序言
  • 1. ctypes实现
  • 2. cython实现
  • 3. c extension实现
  • 4. swig实现
  • 5. 效果测试 & 结论
  • 参考文献
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档