前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python与Golang的网络IO性能对比

Python与Golang的网络IO性能对比

作者头像
glinuxer
发布2019-04-10 15:00:59
2.9K0
发布2019-04-10 15:00:59
举报
文章被收录于专栏:专注网络研发专注网络研发

近期,在做未来服务端新业务的技术语言选型。之前我们的服务端都是使用C++开发,充分榨干了服务器的系统资源 —— 创业公司嘛,服务器也是不小的开销,能节省就节省一点吧。后面考虑到要快速的开发新业务,可能需要使用更高级语言。

在高级语言中,我比较倾心Golang,并不是因为其是google出品,而是因为其下面的三个特点。

一、Golang既可以像高级脚本语言快速开发,又有编译型语言静态检查的优点,避免在运行时出现非期望的错误。

以前用python写过一个数据分析程序,由于数据量很大,在已经运行了几个小时之后,遇到一个非期望的类型,进入了错误处理,这些我都考虑到了。但没想到的是,在错误处理中,有个拼写错误(忘了是函数,还是变量了),导致python抛出来了一个未捕获的异常,运行几个小时的结果直接消失了。这是我对python最不爽的地方。—— 有多少人能保证做单元测试时,能做到100%覆盖,尤其是错误处理的代码。而使用Golang则完全不用担心这个问题,其语法检查在某些点,甚至比C/C++要求的还要严格。

二、Golang的goroutine确实用起来很方便,极大的降低了并行开发的难度。

对于开发者来说,无需设计线程模型,甚至都不用调用线程,一句简单的go语句就直接实现了并行处理。至于Golang是如何操作的,对调用者完全透明。至于性能,让我们直接信任Golang的实现。当然,如果追求接近C++的性能要求,还是要开发者做些处理的。后面可以通过测试程序,了解goroutine的性能。

三、Golang有强制的Coding Style和格式化工具

Coding Style跟讨论哪个语言最好一样,总会引起开发人员无谓的争吵。尤其在某些细微的地方,其实无所谓高低上下,但是对于团队来说,就是喜欢争个面红口赤。我自己对各种Coding Style没有什么倾向,只要是统一的标准就行,使用Golang的强制style和格式化工具,节约大家的时间。

使用高级语言保证了开发速度,但性能也不能太低。比如Python,因为其GIL的限制,我一直对于使用Python实现服务程序持保留意见。我一般只用Python写一些工具,测试脚本等。并且,由于上面所说Python缺少静态检查,在运行中容易出现非期望的错误,影响服务的稳定性。

下面进入今天的正题,“网络IO性能测试”。我选择了C++、Python和Golang进行对比,测试其网络IO性能。测试代码位于:https://github.com/gfreewind/test_cases/tree/master/script_perf/NetIO

测试脚本位于:https://github.com/gfreewind/test_cases/blob/master/script_perf/NetIO/test_script/test_new_conn.sh

使用http_load每秒产生指定数量的TCP连接,并发送HTTP请求,接收回应。

一、C++

没有做特别的优化,但代码量仍然比高级语言多出不少。此处不罗列代码,仅简单说明设计。使用对等的worker线程模型,每个线程绑定到不同的CPU上,利用REUSEADDR和REUSEPORT创建自己的监听套接字,由内核进行流量负载。IO模型使用epoll进行多路复用,同步接收和发送数据。这样的设计,基本上可以实现水平扩展,随着CPU核心数增加,性能也线性上升。

测试结果:一个线程(一个core)支持20K+ RPS,并可以水平扩展。

二、Python

由于Python的GIL限制,为了充分保证多核并发,真正部署时应该会采用多进程的方式。所以这个测试程序,只使用一个线程,IO模型也是使用epoll多路复用,同步接收和发送数据。

测试结果:一个进程支持11K+ RPS左右。

我的Python水平大概是入门水准,写这个测试程序大约用了半小时左右,比写C++要快很多了,但性能只是C++的一半左右。不知道Python高手是否还可以进一步优化这个Python程序,来提高性能。

三、Golang

既然使用了Golang,自然要用Goroutine来做并行处理。所以这个IO模型是每个新建连接,创建一个goroutine进行同步接收和发送。但为了公平,使用taskset限制Golang测试程序只能运行在一个核心上。

测试结果:一个核心支持16K+ RPS

我的Golang水准是绝对的初学者,但写这个测试程序,也只花了不到半小时(跟Python差不多)。在这个测试程序中,每个新建连接,都粗暴的创建一个goroutine处理,没想到性能还可以。但这样的设计,并不能像C++那样水平扩展,无法随核心数目增加而线性提高性能。比如运行这个Golang程序运行在2个核心时,其性能只提高到22K+ RPS左右。如果要重分利用多核,还要做更好的设计,或者也像Python那样简单使用多进程部署。

不过Golang对标的是Python,都是使用一个核心,Golang的性能完善Python。当然,有的人也许会说,那是因为Golang使用了Goroutine,而Python是单线程处理。没错,但Python要像Golang这样每个连接创建一个线程,性能也好不到哪去。如果要做成线程池,那开发时间,不大可能在半小时内完成。(Python3好像支持协程了,这个我没有试过,熟悉的同学可以测试一下。据说,不如Goroutine方便自然)

综合开发速度、难度、性能、以及稳定性,就我而言,我认为Golang要完胜Python。Python虽然有各种丰富的库资源,但对于服务程序来说,Golang的资源也能满足大部分需求了。我愿意让团队在后面的工作中,尝试使用Golang开发服务程序,而继续使用Python来做工具和测试:D

PS:这是测试结果链接https://github.com/gfreewind/test_cases/blob/master/script_perf/NetIO/RESULT.txt

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LinuxerPub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档