Python+Go——带大家一起另寻途径提高计算性能

2024-01-23 18:50

本文主要是介绍Python+Go——带大家一起另寻途径提高计算性能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一腔热血勤珍重,洒去犹能化碧涛。

/1 前言/

Hello各位小伙伴你们好,我们都知道Python是一个生产力很高的语言,小编本人也非常喜欢Python,经常使用Python帮助小编以最高的效率完成最多的事,但是Python的性能,是我们一直诟病的一个问题,尤其是一个大锁GIL,有时候想想简直像吃了苍蝇一样有点难受。

当然了,现在我们大部分程序都是(IO)网络密集型程序,Python足以胜任,但是如果说我们已经存在的项目或者想要开发的项目中,存在有计算密集型的程序场景,我们该怎么办呢?

可能有的小伙伴听说过Python + C\C++,用C\C++重写Python计算密集的地方,来提高性能。当然, 这是一种很好的解决办法,但是我们知道C\C++是有一些学习成本,有没有再更好的解决方案呢?

/2 尝试在Python中调用Golang代码/

后来有幸接触到了Golang,使用了一端时间小编就在想,Python要是能调用Go代码就好了,实在是不想学习C\C++,毕竟C\C++的指针和自己释放内存还是比较有门槛的,Go就很方便了,垃圾自动回收,省的内存泄漏还有天生高并发等优势。

经过不断的查阅了一些资料,踩了一些坑,功夫不负有心人,终于找到了合适的办法,在此分享给大家。

目前最广泛的Python解释器是CPython,Python正好留出来有可以调用C\C++代码的模块,Go经过一些方法,也是可以编译成类似Python可调用的C\C++的文件。

/3 测试环境/

系统:windows

Python解释器:Python 3.7.6(64位)

Go编译器:Go 1.14(64位)

/4 性能对比/

为了更好的体现出来优化之后的效果,我们大概对比一下两个语言在计算密集情况下的差距。

测试:分别计算一个亿(100000000)的累加模拟大量计算。

1)Python代码

import timedef run(n):sum = 0for i in range(n):sum += iprint(sum)if __name__ == '__main__':startTime = time.time()run(100000000)endTime = time.time()print("耗时:", endTime - startTime)

可以看到耗时:10s左右,如下图所示。

2)Go代码

package mainimport ("fmt""time"
)func run(n int) {sum := 0for i := 0; i < n; i++ {sum += i}fmt.Println(sum)
}
func main() {var startTime = time.Now()run(100000000)fmt.Println("耗时:", time.Since(startTime))
}

可以看到耗时:200ms左右,如下图所示。

3)测试结论

我们可以看到,在计算方面,Python和Go是有很大的差距的,如果计算这一块能放在Go上就好了。

别着急,马上开始。

/5 Go代码编译为Python可调用的.so文件/

1)Go代码

功能:接收传入的值进行累加,并且返回最终的累加值。

package mainimport ("C" //C必须导入
)//export run
func run(n int) int{/*必须要export 函数名//是注释的意思,相当于Python中的 #我也是第一次见注释还有作用,黑人三问好???固定写法*/sum := 0for i := 0; i < n; i++ {sum += i}fmt.Println("我是Go代码,我跑完了,我的结果是:",sum)return sum
}func main() {//main函数中什么都不要写,和包名main要对应
}
2)编译为.so文件供Python调用。

命令如下:

go build -buildmode=c-shared -o 输出的.so文件 go源文件

例如:

go build -buildmode=c-shared -o s1.so s1.go

会生成.h文件和.so文件,.so文件供Python调用,如下图所示:


3)Ptyhon调用so文件

将上述生成的.so文件复制到Python项目的同一级目录。

4)Python代码

依然是计算一个亿,关键部分由Go生成的.so执行。

from ctypes import *
import timeif __name__ == '__main__':startTime = time.time()s = CDLL("s1.so")  # 加载s1.so文件result = s.run(100000000)  # 调用Go生成的.so文件里面的run函数print("result:", result)endTime = time.time()print("耗时:", endTime - startTime)


可以看到耗时:0.11s左右,如下图所示。


5)为什么计算的耗时时间不一致,难道是计算错了???

我们可以看到,虽然速度很快,但是Python在调用Go生成的.so文件之后,拿到的返回值竟然是错的,但是在Go中打印的确实对的,这是为什么呢???

不要慌,问题不大!我们来计算一次稍微小一点的,上个100w的。

额,怎么还是错误。

6)我们再来计算更小一些的数,以10023为例,一个不零不整的数值。

    

这次可以看到,结果是对的。但是100w+结果为什么会是错的呢???

我们在上述可以知道,.so文件计算的结果却是正确的,可能是在python接收的时候转换的时候错了,不过别捉急,本章已经有点长了,在下章一定会把这个坑解决的,敬请期待~

/6 小结/

也许Python+Go提高关键地方性能和Python + C\C++相比不是最好的,但是小编认为该方法却是最省心的,毕竟C\C++的门槛是比较高的。


不过话说回来,目前这个性能确实可能也够用了,毕竟Python+Go比Pthon+C\C++的效率可能要高上几倍不止。
用最少的时间撸完最多的代码,加最少的班,人生苦短,我们用Python~~

end

【Java遇见PythonGo】 由一位资深老码农运营,混迹于世界500强外企多年的,做过开发,测试,项目管理,对技术比较痴迷,也是一位后端开发爱好者。

在这里希望给大家分享一些Java,Python和Go语言的编程技巧 ,以及趣味实战干货和面试经验,程序员圈的趣事。欢迎喜欢Java,Python和Go的程序员关注。

Java遇见PythonGo

长按2秒,输入:【面试】

获取大厂Java面试资料

点这里,进菜鸟学PythonB站大本营

这篇关于Python+Go——带大家一起另寻途径提高计算性能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/637196

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <