您现在的位置是:首页 > 资讯杂谈 > 科技杂谈科技杂谈

从 Python 切换到 Go的9 个理由

胜于蓝2020-04-20【科技杂谈】人已围观

简介作者丨Shiv McIntyre译者丨刘雅梦策划丨Tina切换到一种新的编程语言通常是一件大事,特别是当团队成员对原始语言有丰富经验时。今年年初, Stream 将其主要编程语言从 Python

作者丨Shiv McIntyreZRz胜于蓝|优秀个人博客

译者丨刘雅梦ZRz胜于蓝|优秀个人博客

策划丨TinaZRz胜于蓝|优秀个人博客

切换到一种新的编程语言通常是一件大事,特别是当团队成员对原始语言有丰富经验时。今年年初, Stream 将其主要编程语言从 Python 切换到了 Go。本文将会解释他们决定从 Python 切换到 Go 的一些原因。ZRz胜于蓝|优秀个人博客

使用 Go 的理由ZRz胜于蓝|优秀个人博客

理由 1:性能ZRz胜于蓝|优秀个人博客

ZRz胜于蓝|优秀个人博客

Go 非常快。它的性能接近 Java 或 C。Go 的速度比 Python 快 30 倍。ZRz胜于蓝|优秀个人博客

理由 2:语言本身的性能很重要ZRz胜于蓝|优秀个人博客

对于许多应用程序而言,编程语言只是应用程序和数据库之间的粘合剂。语言本身的性能通常并不重要。ZRz胜于蓝|优秀个人博客

Stream 是一家 API 提供商,它为 500 家公司和超过 2 亿的最终用户提供了反馈基础设施。多年来,我们一直在优化 Cassandra、PostgreSQL、Redis 等软件的性能,但是现在我们已经达到了我们所使用编程语言的极限。ZRz胜于蓝|优秀个人博客

Python 是一门伟大的语言,但是对于序列化 / 反序列化、排序和聚合等示例,它的性能非常差。我们经常会遇到性能问题,Cassandra 花费 1ms 的时间来检索数据,而 Python 将其转换成对象则需要 10ms 的时间。ZRz胜于蓝|优秀个人博客

理由 3:开发人员的效率,而无需太多创新ZRz胜于蓝|优秀个人博客

请看下“如何开始学习 Go ”教程中的如下 Go 代码片段。ZRz胜于蓝|优秀个人博客

type openWeatherMap struct{}func (w openWeatherMap) temperature(city string) (float64, error) { resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city) if err != nil { return 0, err } defer resp.Body.Close() var d struct { Main struct { Kelvin float64 `json:"temp"` } `json:"main"` } if err := json.NewDecoder(resp.Body).Decode(&d); err != nil { return 0, err } log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin) return d.Main.Kelvin, nil}ZRz胜于蓝|优秀个人博客

如果你刚开始学习 Go,阅读这段代码不会有太多惊喜。它演示了赋值、数据结构、指针、格式化和内置的 HTTP 库。ZRz胜于蓝|优秀个人博客

从我首次接触编程开始,我总是喜欢使用 Python 的高级特性。Python 使我们能从正在编写的代码中获得很好的想法。例如,我们可以:ZRz胜于蓝|优秀个人博客

初始化代码时,使用元类(MetaClasses)自己注册类ZRz胜于蓝|优秀个人博客

切换“True”和“False”ZRz胜于蓝|优秀个人博客

将一个函数添加到内置函数列表中ZRz胜于蓝|优秀个人博客

通过魔术方法(Magic Method)重载运算符ZRz胜于蓝|优秀个人博客

这些特性非常有趣,但是,大多数程序员都认为这会增加阅读他人代码的难度。ZRz胜于蓝|优秀个人博客

Go 会迫使我们使用最基本的东西,这使得阅读他人代码变得更容易。ZRz胜于蓝|优秀个人博客

注:当然,“容易”取决于具体的项目。如果只是创建一个基本的 CRUD API,我仍然建议使用 Django& DRF 或 Rails。ZRz胜于蓝|优秀个人博客

理由 4 :并发和通道ZRz胜于蓝|优秀个人博客

作为一门编程语言,Go 总是尽可能地保持简单。它没有引入太多的新概念,因为它的目标是创建一门易于使用的编程语言。它唯一具有创新性的地方是 Goroutines(go 协程)和 Channels(通道)。Goroutines 是 Go 的轻量级线程解决方案,而 Channels 是与 Goss 交互的首选方式。ZRz胜于蓝|优秀个人博客

Goroutines 非常轻量,仅需要几千字节的额外内存。而且由于 Goroutine 如此轻量,因此可以同时运行数百甚至数千个 Goroutine。ZRz胜于蓝|优秀个人博客

我们可以使用 Channels 在 Goroutines 之间进行通信。Go 运行时处理所有的内部复杂性。基于 Goroutines 和 Channels 的并发方案使应用程序能够轻松使用所有可用的 CPU 内核并处理并发 IoO,而无需进行复杂的开发。与 Python/Java 相比,在 Goroutines 上运行函数只需要很少的固定代码。我们只需要使用关键字“go”调用函数即可:ZRz胜于蓝|优秀个人博客

package mainimport ( "fmt" "time")func say(s string) { for i := 0; iZRz胜于蓝|优秀个人博客

https://tour.golang.org/concurrency/1ZRz胜于蓝|优秀个人博客

Go 的并发解决方案非常易于使用。与开发人员必须密切关注异步代码处理方式的 Node 相比,这是一个非常有趣的方案。ZRz胜于蓝|优秀个人博客

Go 并发的另一个关注点是竞态检测。它使应用程序能够很容易地知道异步代码中是否存在任何竞态条件。ZRz胜于蓝|优秀个人博客

以下是一些学习 Go 和 Channels 的重要资源:ZRz胜于蓝|优秀个人博客

https://gobyexample.com/channelsZRz胜于蓝|优秀个人博客

https://tour.golang.org/concurrency/2ZRz胜于蓝|优秀个人博客

http://guzalexander.com/2013/12/06/golang-channels-tutorial.htmlZRz胜于蓝|优秀个人博客

https://www.golang-book.com/books/intro/10ZRz胜于蓝|优秀个人博客

https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.htmlZRz胜于蓝|优秀个人博客

https://softwareengineering.stackexchange.com/questions/222642/are-go-langs-goroutine-pools-just-green-threadsZRz胜于蓝|优秀个人博客

理由 5:编译速度快ZRz胜于蓝|优秀个人博客

用 Go 编写的最大的微服务项目只需 6 秒就可以编译完成。与 Java 和 C 等语言的龟速(turtle-speed)编译相比,Go 的极快编译速度是它的主要生产力。ZRz胜于蓝|优秀个人博客

理由 6:组件团队的能力ZRz胜于蓝|优秀个人博客

让我们从这些数据开始:Go 的开发人员没有 C 和 Java 的开发人员多。根据 StackOverflow 的统计,有 38%的开发人员使用 Java,19.3%的开发人员使用 C,但只有 4.6%的开发人员使用 Go。GitHub 数据也显示出了类似的趋势:Go 比 Erlang、Scala 和 Elixir 等语言使用得更广泛,但不如 Java 和 C 那么流行。ZRz胜于蓝|优秀个人博客

幸运的是,Go 是一门非常简单易学的语言。它只提供了我们需要的基本功能,而没有提供其他附加功能。它引入了一些新概念,例如“ defer ”声明和内置的“go routines”以及 Channels 并发管理等。团队中的任何 Python、Elixir、C、Scala 或 Java 开发人员都可以在一个月内学习会怎么使用 Go 编程,因为 Go 非常简单。ZRz胜于蓝|优秀个人博客

与其他语言相比,我们发现建立 Go 开发团队更加容易。如果我们在竞争激烈的环境中(例如在博尔德和阿姆斯特丹)招聘,这是一个非常重要的优势。ZRz胜于蓝|优秀个人博客

理由 7:强大的生态系统ZRz胜于蓝|优秀个人博客

生态系统对于我们这样规模的团队(大约 20 人)来说非常重要。如果你不得不重新设计所有的功能,你就不能为你的客户创造价值。Go 为我们经常使用的工具提供了强大的支持。例如,Redis、RabbitMQ、PostgreSQL、模板解析、任务调度、表达式解析和 DBRocks 都可以使用现有的库。ZRz胜于蓝|优秀个人博客

与其他新语言(例如 Rust 或 Elixir)相比,Go 具有巨大的生态系统优势。尽管它不能与 Java、Python 或 Node 相提并论,但是我们是可以找到许多能够满足基本需求的高质量软件包。ZRz胜于蓝|优秀个人博客

理由 8:Gofmt,强制代码格式化ZRz胜于蓝|优秀个人博客

Gofmt 是一个优秀的命令行程序,它内置于 Go 编译器中,可用于格式化代码。在功能方面,它类似于 Python 的 autopep 8。我们大多数人都不喜欢争论制表符(tabs)和空格(spaces),但格式化的目标始终是一致的,实际的格式标准则无关紧要。Gofmt 以一种形式化的方式来格式化代码,以避免所有这些争论。ZRz胜于蓝|优秀个人博客

理由 9:gRPC 以及 Protocol BuffersZRz胜于蓝|优秀个人博客

Go 为 Protocol Buffers 和 gRPC 提供了一流的支持。它将这两个工具完美地结合在一起,构建了一个通过 RPC 进行通信的微服务。我们只需编写一个定义了 RPC 调用及其参数的清单文件,服务端和客户端就可以据此自动生成适当的代码了。这不仅速度快,而且网络占用空间小,使用起来更方便。ZRz胜于蓝|优秀个人博客

其他语言(如 C、Java、Python 和 Ruby)中的客户端代码也可以基于相同的清单文件生成。这样,就不会与内部 REST 接口发生冲突了,而且我们也不必每次都编写几乎相同的客户端和服务端代码。ZRz胜于蓝|优秀个人博客

使用 Golang 的缺点ZRz胜于蓝|优秀个人博客

缺点 1 :缺乏框架ZRz胜于蓝|优秀个人博客

Go 不像 Ruby 的 Rails、Python 或 Django 或 PHP 的 Laravel,它没有一个主要的框架。这个话题在 Go 社区引起了激烈的争论,许多人认为不应该使用现有的框架来启动项目。在某些情况下,我完全同意这一点。但是,如果我们想要构建一个简单的 CRUD API,那么使用 Django/DJRF、Rails Laravel 或 Phoenix 则会更简单。ZRz胜于蓝|优秀个人博客

缺点 2:错误处理ZRz胜于蓝|优秀个人博客

Go 通过简单地从函数中返回错误的形式来处理错误。尽管这种方案是可行的,但是它很容易失去错误的范围,从而很难向用户提供有价值的错误信息。错误包可以通过返回错误的上下文和错误堆栈来解决该问题。ZRz胜于蓝|优秀个人博客

还有一个问题,那就是它很容易忘记去处理错误。尽管诸如 errcheck 和 megacheck 之类的静态分析工具可以避免这些错误,但这始终并不完善。也许我们应该期待一种语言级别的错误处理方案。ZRz胜于蓝|优秀个人博客

缺点 3:包管理ZRz胜于蓝|优秀个人博客

Go 的包管理并不完善。默认情况下,它无法指定依赖项的特定版本,也无法创建可重用的构建方案。Python、Node 和 Ruby 都有更好的包管理系统。但是,如果能使用正确的工具,Go 的包管理也可以变得更简单。ZRz胜于蓝|优秀个人博客

我们可以使用 Dep 来管理指定固定版本的依赖项。此外,我们还提供了一个名为 VirtualGo 的开源工具,用于多项目管理。ZRz胜于蓝|优秀个人博客

Python vs GoZRz胜于蓝|优秀个人博客

我们做了一个有趣的实验,用 Go 重写了原来由 Python 编写的 feed 流。请看一下该排序方法的示例:ZRz胜于蓝|优秀个人博客

{ "functions": { "simple_gauss": { "base": "decay_gauss", "scale": "5d", "offset": "1d", "decay": "0.3" }, "popularity_gauss": { "base": "decay_gauss", "scale": "100", "offset": "5", "decay": "0.5" } }, "defaults": { "popularity": 1 }, "score": "simple_gauss(time)*popularity"}ZRz胜于蓝|优秀个人博客

Python 和 Go 的代码都需要执行如下操作来支持此排序方法:ZRz胜于蓝|优秀个人博客

解析分数表达式,将“simple_gauss”转换为函数,输入活动并输出分数ZRz胜于蓝|优秀个人博客

通过 JSON 配置创建函数。例如,我们想要“simple_gauss”在 scale 为 5 天、offset 为 1 天、factor 为 0.3 时调用“decay_gauss”。ZRz胜于蓝|优秀个人博客

当字段没有值时,解析“defaults”配置并采用默认值。ZRz胜于蓝|优秀个人博客

从步骤 1 开始使用该函数,对 feed 中的所有活动进行评分。ZRz胜于蓝|优秀个人博客

开发 Python 版的排序(Sort )代码花了大约三天的时间,其中包括代码编写、单元测试和文档编写。接下来,我们花了大约 2 周的时间来优化代码。其中一种优化方法是将分数表达式 simple_gauss(time)*popularity 转换为抽象语法树。我们还实现了可用于预测分数的缓存逻辑。ZRz胜于蓝|优秀个人博客

相比之下,开发此代码的 Go 版花了大约四天的时间,并且在后期不需要进一步地优化性能。因此,尽管 Python 最初的开发速度更快,但是 Go 版最终需要的工作量更少。另一个优势是,Go 代码比我们高度优化的 Python 代码还要快 40 倍。ZRz胜于蓝|优秀个人博客

当然,这只是说明我们切换到 Go 后性能提升的一个简单示例:ZRz胜于蓝|优秀个人博客

排序代码是我用 Go 编写的第一个项目。ZRz胜于蓝|优秀个人博客

Go 代码是在 Python 代码之后编写的,因此对项目的理解更加深入。ZRz胜于蓝|优秀个人博客

Go 的表达式解析库的质量更高ZRz胜于蓝|优秀个人博客

你的经历可能会有所不同。与 Python 相比,使用 Go 构建系统中的某些其他组件需要花费更多的时间。通常,编写 Go 代码需要付出更多的努力。但是,优化代码性能所需的时间会更少。ZRz胜于蓝|优秀个人博客

Elixir vs GoZRz胜于蓝|优秀个人博客

我们想要评估的另一种语言是 Elixir 。Elixir 是一门建立在 Erlang 虚拟机上的引人入胜的语言。我之所以这么说,是因为我们的一个项目团队非常精通该语言。ZRz胜于蓝|优秀个人博客

出于这个原因,我们注意到 Go 的原始性能更好。Go 和 Elixir 都能支持数千个并发请求。但是,如果我们查看单个请求的性能,Go 要快得多。我们选择 Go 的另一个原因是它的生态系统。对于我们需要的组件来说,Go 具有更成熟的库,而 Elixir 尚不适合用于生产。同时,也很难招聘到 Elixir 开发人员或对开发人员进行 Elixir 培训。ZRz胜于蓝|优秀个人博客

结 论ZRz胜于蓝|优秀个人博客

Go 是一种性能非常高的语言,并且它对并发的支持非常强大。它差不多与 C 和 Java 一样快了。尽管 Go 的编译速度比 Python 或 Ruby 慢,但我们可以节省出大量的优化代码时间。ZRz胜于蓝|优秀个人博客

Go 对于新手而言具有庞大的生态系统,它易于学习使用,具有超高的性能,并且对并发有强大的支持,此外,它还具有非常高效的开发环境。这些特性使 Go 成为开发人员最合适的选择。ZRz胜于蓝|优秀个人博客

Tags:

Python   Go

很赞哦! ()

文章评论

当前时间

快速排名

  • 网站建设|万词霸屏,企业软文推广,刷下拉框
  • 快速排名:不用再等SEO三个月,只需3-7天即可把行业关键词覆盖百度搜索引擎首页,点击不收费,排名报表,真实访问量报表一目了然。

合作加盟

  • 扫码请注明来意,否则不会通过
  • 填写商户姓名不要带有“超市”,“便利店” ,“百货”等
  • 扫码成为快钱代理
  • 扫码加站长微信,为您推荐快钱总部负责人
  • 快钱POSS机(电签版)
  • 1,免押版:签约费率快捷交易0.38%,常规交易0.65%
  • 贷记卡单笔≥3000元视为激活
  • 2,,有押版:签约快捷交易0.38%,常规交易0.65%
  • 激活首刷≥99元,扣除99元系统服务费,多出部分shishi到账
  • 电签版ipos参与每月扶持奖励
  • 电签版ipos与Mpos单独考核台均
  • 30台以上有效激活奖励3000元扶持金
  • 当月交易额≥3000元的为活跃用户

本站推荐

站点信息

  • 建站时间:2018-10-24
  • 网站程序:帝国CMS7.5
  • 主题模板《今夕何夕》
  • 文章统计7613篇文章
  • 标签管理标签云
  • 统计数据百度统计
  • 扫描二维码:请注明来意,否则不会通过
  • 微信号:扫描二维码,关注我们
歌名 - 歌手
0:00