从 Python 切换到 Go的9 个理由

文章图片
作者丨ShivMcIntyre
译者丨刘雅梦
策划丨Tina
切换到一种新的编程语言通常是一件大事 , 特别是当团队成员对原始语言有丰富经验时 。 今年年初 , Stream将其主要编程语言从Python切换到了Go 。 本文将会解释他们决定从Python切换到Go的一些原因 。
使用Go的理由
理由1:性能

文章图片
Go非常快 。 它的性能接近Java或C 。 Go的速度比Python快30倍 。
理由2:语言本身的性能很重要
对于许多应用程序而言 , 编程语言只是应用程序和数据库之间的粘合剂 。 语言本身的性能通常并不重要 。
【从 Python 切换到 Go的9 个理由】Stream是一家API提供商 , 它为500家公司和超过2亿的最终用户提供了反馈基础设施 。 多年来 , 我们一直在优化Cassandra、PostgreSQL、Redis等软件的性能 , 但是现在我们已经达到了我们所使用编程语言的极限 。
Python是一门伟大的语言 , 但是对于序列化/反序列化、排序和聚合等示例 , 它的性能非常差 。 我们经常会遇到性能问题 , Cassandra花费1ms的时间来检索数据 , 而Python将其转换成对象则需要10ms的时间 。
理由3:开发人员的效率 , 而无需太多创新
请看下“如何开始学习Go”教程中的如下Go代码片段 。
typeopenWeatherMapstruct{}func(wopenWeatherMap)temperature(citystring)(float64,error){resp,err:=http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q="+city)iferr!=nil{return0,err}deferresp.Body.Close()vardstruct{Mainstruct{Kelvinfloat64`json:"temp"`}`json:"main"`}iferr:=json.NewDecoder(resp.Body).Decode(&d);err!=nil{return0,err}log.Printf("openWeatherMap:%s:%.2f",city,d.Main.Kelvin)returnd.Main.Kelvin,nil}
如果你刚开始学习Go , 阅读这段代码不会有太多惊喜 。 它演示了赋值、数据结构、指针、格式化和内置的HTTP库 。
从我首次接触编程开始 , 我总是喜欢使用Python的高级特性 。 Python使我们能从正在编写的代码中获得很好的想法 。 例如 , 我们可以:
初始化代码时 , 使用元类(MetaClasses)自己注册类
切换“True”和“False”
将一个函数添加到内置函数列表中
通过魔术方法(MagicMethod)重载运算符
这些特性非常有趣 , 但是 , 大多数程序员都认为这会增加阅读他人代码的难度 。
Go会迫使我们使用最基本的东西 , 这使得阅读他人代码变得更容易 。
注:当然 , “容易”取决于具体的项目 。 如果只是创建一个基本的CRUDAPI , 我仍然建议使用Django&DRF或Rails 。
理由4:并发和通道
作为一门编程语言 , Go总是尽可能地保持简单 。 它没有引入太多的新概念 , 因为它的目标是创建一门易于使用的编程语言 。 它唯一具有创新性的地方是Goroutines(go协程)和Channels(通道) 。 Goroutines是Go的轻量级线程解决方案 , 而Channels是与Goss交互的首选方式 。
Goroutines非常轻量 , 仅需要几千字节的额外内存 。 而且由于Goroutine如此轻量 , 因此可以同时运行数百甚至数千个Goroutine 。
我们可以使用Channels在Goroutines之间进行通信 。 Go运行时处理所有的内部复杂性 。 基于Goroutines和Channels的并发方案使应用程序能够轻松使用所有可用的CPU内核并处理并发IoO , 而无需进行复杂的开发 。 与Python/Java相比 , 在Goroutines上运行函数只需要很少的固定代码 。 我们只需要使用关键字“go”调用函数即可:
packagemainimport("fmt""time")funcsay(sstring){fori:=0;i
https://tour.golang.org/concurrency/1
Go的并发解决方案非常易于使用 。 与开发人员必须密切关注异步代码处理方式的Node相比 , 这是一个非常有趣的方案 。
Go并发的另一个关注点是竞态检测 。 它使应用程序能够很容易地知道异步代码中是否存在任何竞态条件 。
以下是一些学习Go和Channels的重要资源:
https://gobyexample.com/channels
https://tour.golang.org/concurrency/2
http://guzalexander.com/2013/12/06/golang-channels-tutorial.html
https://www.golang-book.com/books/intro/10
https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.html
https://softwareengineering.stackexchange.com/questions/222642/are-go-langs-goroutine-pools-just-green-threads
理由5:编译速度快
用Go编写的最大的微服务项目只需6秒就可以编译完成 。 与Java和C等语言的龟速(turtle-speed)编译相比 , Go的极快编译速度是它的主要生产力 。
理由6:组件团队的能力
让我们从这些数据开始:Go的开发人员没有C和Java的开发人员多 。 根据StackOverflow的统计 , 有38%的开发人员使用Java , 19.3%的开发人员使用C , 但只有4.6%的开发人员使用Go 。 GitHub数据也显示出了类似的趋势:Go比Erlang、Scala和Elixir等语言使用得更广泛 , 但不如Java和C那么流行 。
幸运的是 , Go是一门非常简单易学的语言 。 它只提供了我们需要的基本功能 , 而没有提供其他附加功能 。 它引入了一些新概念 , 例如“defer”声明和内置的“goroutines”以及Channels并发管理等 。 团队中的任何Python、Elixir、C、Scala或Java开发人员都可以在一个月内学习会怎么使用Go编程 , 因为Go非常简单 。
与其他语言相比 , 我们发现建立Go开发团队更加容易 。 如果我们在竞争激烈的环境中(例如在博尔德和阿姆斯特丹)招聘 , 这是一个非常重要的优势 。
理由7:强大的生态系统
生态系统对于我们这样规模的团队(大约20人)来说非常重要 。 如果你不得不重新设计所有的功能 , 你就不能为你的客户创造价值 。 Go为我们经常使用的工具提供了强大的支持 。 例如 , Redis、RabbitMQ、PostgreSQL、模板解析、任务调度、表达式解析和DBRocks都可以使用现有的库 。
与其他新语言(例如Rust或Elixir)相比 , Go具有巨大的生态系统优势 。 尽管它不能与Java、Python或Node相提并论 , 但是我们是可以找到许多能够满足基本需求的高质量软件包 。
理由8:Gofmt , 强制代码格式化
Gofmt是一个优秀的命令行程序 , 它内置于Go编译器中 , 可用于格式化代码 。 在功能方面 , 它类似于Python的autopep8 。 我们大多数人都不喜欢争论制表符(tabs)和空格(spaces) , 但格式化的目标始终是一致的 , 实际的格式标准则无关紧要 。 Gofmt以一种形式化的方式来格式化代码 , 以避免所有这些争论 。
理由9:gRPC以及ProtocolBuffers
Go为ProtocolBuffers和gRPC提供了一流的支持 。 它将这两个工具完美地结合在一起 , 构建了一个通过RPC进行通信的微服务 。 我们只需编写一个定义了RPC调用及其参数的清单文件 , 服务端和客户端就可以据此自动生成适当的代码了 。 这不仅速度快 , 而且网络占用空间小 , 使用起来更方便 。
其他语言(如C、Java、Python和Ruby)中的客户端代码也可以基于相同的清单文件生成 。 这样 , 就不会与内部REST接口发生冲突了 , 而且我们也不必每次都编写几乎相同的客户端和服务端代码 。
使用Golang的缺点
缺点1:缺乏框架
Go不像Ruby的Rails、Python或Django或PHP的Laravel , 它没有一个主要的框架 。 这个话题在Go社区引起了激烈的争论 , 许多人认为不应该使用现有的框架来启动项目 。 在某些情况下 , 我完全同意这一点 。 但是 , 如果我们想要构建一个简单的CRUDAPI , 那么使用Django/DJRF、RailsLaravel或Phoenix则会更简单 。
缺点2:错误处理
Go通过简单地从函数中返回错误的形式来处理错误 。 尽管这种方案是可行的 , 但是它很容易失去错误的范围 , 从而很难向用户提供有价值的错误信息 。 错误包可以通过返回错误的上下文和错误堆栈来解决该问题 。
还有一个问题 , 那就是它很容易忘记去处理错误 。 尽管诸如errcheck和megacheck之类的静态分析工具可以避免这些错误 , 但这始终并不完善 。 也许我们应该期待一种语言级别的错误处理方案 。
缺点3:包管理
Go的包管理并不完善 。 默认情况下 , 它无法指定依赖项的特定版本 , 也无法创建可重用的构建方案 。 Python、Node和Ruby都有更好的包管理系统 。 但是 , 如果能使用正确的工具 , Go的包管理也可以变得更简单 。
我们可以使用Dep来管理指定固定版本的依赖项 。 此外 , 我们还提供了一个名为VirtualGo的开源工具 , 用于多项目管理 。
PythonvsGo
我们做了一个有趣的实验 , 用Go重写了原来由Python编写的feed流 。 请看一下该排序方法的示例:
{"functions":{"simple_gauss":{"base":"decay_gauss","scale":"5d","offset":"1d","decay":"0.3
推荐阅读
- 路虎库存成灾,从68万降到45万仍无人问津,经销商:给钱就卖!
- 央视新闻客户端这条传播链从1到200才两周!恐怖的投币练歌房:唱5首歌飞沫遍身
- 粤港澳大湾区战略呼唤网红经济助力
- 从24号开始,佳音上门,好运连连,事业顺风顺水的4个星座
- 为扳倒汉兰达,这豪车拼了,从32万降到26万,起步2.0T爆241马力
- 3艘宙斯盾舰逼近领海,委内瑞拉不再放狠话,2艘幽灵从港口消失
- 约旦海岸线26公里,一部分从沙特交换来,付出多大代价?
- 中美蜜月期下的暗战,从超-7战斗机立项到下马背后鲜为人知的博弈
- 千里护送认亲!聊城聋哑老人走失12年从湖北归来团聚
- 原创 女人过得如不如意,从这几个方面一看便知,装不出来的
