Python:ctypes模块调用go代码

本文通过案例对比了Python和Go的计算效率,展示了Go在循环计算上的优势。并介绍了如何通过Python的ctypes模块调用Go编译的.so库,从而显著提高Python代码的执行速度。详细步骤包括Go代码编写、编译生成.so文件以及Python调用.so文件的实现。实验结果显示,使用ctypes调用Go代码将执行时间从约5秒降低到50ms,性能提升明显。

简介:ctypes 是 Python 的外部函数库。它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。

注意事项
Python是利用ctypes来跟so模块进行交互,其中存在着一个代码的翻译过程,包括数据类型的翻译,如果需要传参获取接收返回值,需要在golang中将参数按照下表对应,定义成C语言的数据类型。

基础数据类型:ctypes 定义的一些和C兼容的基本数据类型
在这里插入图片描述
虽然Python优点很多,但是有一个致命的缺点就是运行速度太慢。
同样是循环计算:

案例1:Python

import datetime


def calc_test(loop):
    s = 0
    for i in range(loop):
        for j in range(loop):
            s += 1


if __name__ == '__main__':
    loop = 10000
    print(datetime.datetime.now())
    calc_test(loop)
    print(datetime.datetime.now())
    
    # 2021-12-14 11:04:26.450916
    # 2021-12-14 11:04:31.274916
    # 耗时大约5秒左右。

案例2:Go - main.go

package main
// 必须导入C这个包。
// 注释 export Test不能省略

import (
  "C"
  "fmt"
  "time"
)

//export Test
func Test(loop int) int {
  Sum := 0
  t1 := time.Now()
  fmt.Println(t1)
  for i := 0; i < loop; i++ {
    for j := 0; j < loop; j++ {
      Sum++
    }
  }
  t2 := time.Now()
  fmt.Println(t2)
  fmt.Println("执行用时:", t2.Sub(t1))
  return Sum
}
func main() {
  loop := 10000
  Test(loop)
  //2021-12-14 11:06:03.8221084 +0800 CST m=+0.009999601
  //2021-12-14 11:06:03.8861067 +0800 CST m=+0.073997901
  //执行用时:63.9983ms
  //go build -buildmode=c-shared -o _test.so main.go
}

结论:一般情况下,普通计算Go的效率远远高于Python。

Python调用 Go 语言写的代码的步骤:
1、编写go代码
2、编译生成.so文件
3、通过ctypes模块调用

编译生成.so文件:需要注意的是需要先安装gcc编译器,否则会抛出异常

running gcc failed: exec: "gcc": executable file not found in %PATH%

注意事项:go代码中注释//export Test不能省略,因为在编译成.so文件的时候,编译器会寻找这个注释。为正常编译,必须导入C这个包。

安装gcc编译器攻略

https://blog.csdn.net/xia_2017/article/details/105545789

图片
执行编译命令:

go build -buildmode=c-shared -o _test.so main.go

执行完成后会生成.so文件:
在这里插入图片描述

通过ctypes模块调用:

# -*- coding: utf-8 -*-
import ctypes
import time


so = ctypes.cdll.LoadLibrary(r'.\_test.so')
calc = so.Test

start = time.time()
sum_number = calc(10000)
end = time.time()
print(f'累计和为:{sum_number},耗时:{end - start}')
# 2021-12-15 14:21:00.3328247 +0800 CST m=+0.005614901
# 2021-12-15 14:21:00.3771324 +0800 CST m=+0.049922601
# 执行用时:44.3077ms
# 累计和为:100000000,耗时:0.051664113998413086

执行结果:

图片

从结果上看,执行效率由5秒左右,提升到了50ms,效果明显。

图片

微信公众号:玩转测试开发
欢迎关注,共同进步,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值