python 程序中调用go
Golang构建Python高性能模块
虽然Python优点很多,但是有一个致命的缺点就是运行速度太慢,那么Python程序需要一些计算量比较大的模块时一般会调用c或者c++的代码来重写,但是c/c++编写代码代价太高,耗费太多的人力,开发周期太长,那么就想到来一个折中的方法是用golang语言。
虽然golang性能比不上c、c++,但是golang天生的高并发,以及编译速度超级快,而且还自带垃圾回收机制,不用开发者自己去管理内存,开发效率高。所以在Python程序遇到大计算量时,可以考虑调用go模块。接下来我们来看看如何在利用go模块写Python第三方模块,以及如何在Python中导入并调用。
下面构建一个go python 模块:
package main
import "C"
//指定那些函数能被外部调用
//export test
func test() int{
//计算 0-100000 的和
var s int
for a := 0; a <= 1000000; a++ {
s += a
}
return s
}
func main(){
}
编译生成动态链接库,生成的.so文件可以被python加载并调用
但是有一个需要注意的地方:
Python是利用ctypes
来跟so模块进行交互,其中存在着一个代码的翻译过程,包括数据类型的翻译,如果需要传参获取接收返回值,需要在golang中将参数按照下表对应,定义成C语言的数据类型。
python,ctypes , c 对应类型参考 python 官方文档:https://docs.python.org/3.5/library/ctypes.html
这里列举几个常用的数据类型
ctypes type(ctypes类型) | C type(c语言类型) | Python type(python类型) |
---|---|---|
c_bool | _Bool | bool (1) |
c_char | char | 1-character bytes object |
c_wchar | wchar_t | 1-character string |
c_byte | char | int |
c_char_p | char * (NUL terminated) | 1-character bytes object |
c_wchar_p | wchar_t * (NUL terminated) | string or None |
比如创建一个带参数的go函数:
// 指定接收的参数为c类型的字符串,返回c类型字符串
//pxport addstr
func addstr(a,b * C.char) *C.char{
merge := C.GoString(a) + C.GoString(b)
return C.CString(merge)
}
写好go代码之后重新生成动态链接库
go build -buildmode=c-shared -o hello.so src/hello.go
在python中调用带参数的go模块需要显式指定参数的类型以及返回的数据类型。argtypes指定参数类型,restype
指定返回值类型。
from ctypes import CDLL
add = CDLL('./hello.so').addstr #调用go模块
# 显式声明参数和返回的期望类型
add.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
add.restype = ctypes.c_char_p
print(add('haha','hehe'))
# 无参数,则可直接调用
t = CDLL('./hello.so').test #调用go模块
print(t())
python 中调用go模块,并统计两个模块循环1百万次累加的时间,查看go跟python执行效率
# coding=utf-8
import time
from ctypes import CDLL
import ctypes
def xu():
# python 计算累加
sum = 0
for i in range(0,1000000+1):
sum += i
return sum
if __name__ =="__main__":
add = CDLL('./hello.so').addstr #调用go模块addstr方法
# 显式声明参数和返回的期望类型
add.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
add.restype = ctypes.c_char_p
print(add('haha','hehe'))
# go 一百万次累加
start = time.time()
t = CDLL('./hello.so').test #调用go模块test方法
t.restype = ctypes.c_int64 # 返回int64类型
print("go执行结果:%s"%t())
end = time.time()
print("go :1000000 累加耗时 %.2f" %(end-start))
# python累加一百万次
start = time.time()
print("python执行结果:%s"%xu())
end = time.time()
print("python :1000000 累加耗时 %.2f" %(end-start))
单从循环一百万次来看,go的效率要高很多。
Python 号称开发速度快,而go语言在静态语言中也号称是开发开发速度最快的,go的高并发刚好可以填补Python GIL导致Python多线程不是真的多线程这一缺点。
本文主要讲解了如何使用golang写Python模块,以及在Python中如何调用go模块,主要要注意的是参数类型的转换。
python 程序中调用go的更多相关文章
- 在Python程序中调用Java代码的实现
<原创不易,转载请标明出处:https://www.cnblogs.com/bandaobudaoweng/p/10785766.html> 前言 开发Python程序,需求中需要用到Ja ...
- Java程序中调用Python脚本的方法
在程序开发中,有时候需要Java程序中调用相关Python脚本,以下内容记录了先关步骤和可能出现问题的解决办法. 1.在Eclipse中新建Maven工程: 2.pom.xml文件中添加如下依赖包之后 ...
- 在Python程序中的进程操作,multiprocess.Process模块
在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...
- python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)
昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...
- python程序中使用MySQL数据库
目录 python程序中使用MySQL数据库 1 pymysql连接数据库 2 sql 注入 3 增删改查操作 4 pymysql使用总结 python程序中使用MySQL数据库 1.python中使 ...
- Python程序中的进程操作--—--开启多进程
Python程序中的进程操作-----开启多进程 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创 ...
- Python程序中的线程操作(线程池)-concurrent模块
目录 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecut ...
- 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案
方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...
- iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )
在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用:
随机推荐
- Python之旅.第二章数据类型 3.19/3.20/3.21/3.22/3.23
一.数字类型 1.int类型: 基本使用: 用途:用于年龄,手机号,身份证号: 定义: age=18: 常用操作+内置方法: 正常的运算赋值: 进制转换: print(bin(3)); 把十进制3转换 ...
- Windows Powershell脚本执行
在cmd下执行powershell进入shell模式: 变量定义:$i = 10 $a = ifconfig | findstr "192" Windows下的命令都可以执行如: ...
- Web系统Login拦截器
所需要导入的包类:import org.springframework.web.servlet.HandleInterceptor;(拦截器要继承该类) public class loginInter ...
- IDE-Ecplise-代码注释 模版 编码规范 配色
说明: 代码注释主要用于方便代码后期维护,编码规范,增加代码阅读性和维护性.因网上看到的很多博客中片段局多,故整理后重写一篇,方便交流学习. 先看下加过注释模版后的效果. 如上图所示,创建类,方法和继 ...
- windbg分析Kernel32.dll导出表
写在前面的话: 继续上篇,在获得了Kernel32.dll基址的基础上,分析它的导出表结构: 对PE结构不太熟悉的同学,可以参考看雪论坛里的一篇帖子:https://bbs.pediy.com/thr ...
- [LuoguP1113] 杂物 - 拓扑排序
其实只是纪念下第一篇洛谷题解? Description John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及 ...
- semver(Semantic Versioning)
Based on semver, you can use Hyphen Ranges X.Y.Z - A.B.C 1.2.3-2.3.4 Indicates >=1.2.3 <=2.3.4 ...
- 详解Class
Classs是es6提供的类,相当于es5的构造函数. 写法: class Foo { constructor () { // new 的时候会调用该方法,可以通过return改变构造函数的返回值 r ...
- python自带的web服务器
python自带的web服务器 python自带的包可以建立简单的web服务器 BaseHTTPServer 提供基本的web服务和处理类 SimpleHTTPServer 包含执行get请求的Sim ...
- JavaScript实现轮播图(隔3秒显示一张图)
<!DOCTYPE html><html> <head> <script> var time; function init(){ //获取div里面的东 ...