python语言的生态库都是官方开发的_放弃Python转向Go语言:我们找到了以下9大理由...
原标题:放弃Python转向Go语言:我们找到了以下9大理由
转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时。今年 Stream 团队的主要编程语言从 Python 转向了 Go。本文解释了其背后的九大原因以及如何做好这一转换。
为什么使用 Go
原因 1:性能
Go 极其地快。其性能与 Java 或 C++相似。在我们的使用中,Go 一般比 Python 要快 30 倍。以下是 Go 与 Java 之间的基准比较:
原因 2:语言性能很重要
对很多应用来说,编程语言只是简单充当了其与数据集之间的胶水。语言本身的性能常常无关轻重。
但是 Stream 是一个 API 提供商,服务于世界 500 强以及超过 2 亿的终端用户。数年来我们已经优化了 Cassandra、PostgreSQL、Redis 等等,然而最终抵达了所使用语言的极限。
Python 非常棒,但是其在序列化/去序列化、排序和聚合中表现欠佳。我们经常会遇到这样的问题:Cassandra 用时 1ms 检索了数据,Python 却需要 10ms 将其转化成对象。
原因 3:开发者效率&不要过于创新
看一下绝佳的入门教程《开始学习 Go 语言》(http://howistart.org/posts/go/1/)中的一小段代码:
package main 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)
iferr != nil {
return0, err } defer resp. Body. Close ()
var d struct { Main struct { Kelvin float64 `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}
如果你是一个新手,看到这段代码你并不会感到吃惊。它展示了多种赋值、数据结构、指针、格式化以及内置的 HTTP 库。
当我第一次编程时,我很喜欢使用 Python 的高阶功能。Python 允许你创造性地使用正在编写的代码,比如,你可以:
在代码初始化时,使用 MetaClasses 自行注册类别
置换真假
添加函数到内置函数列表中
通过奇妙的方法重载运算符
毋庸置疑这些代码很有趣,但也使得在读取其他人的工作时,代码变得难以理解。
Go 强迫你坚持打牢基础,这也就为读取任意代码带来了便利,并能很快搞明白当下发生的事情。
注意:当然如何容易还是要取决于你的使用案例。如果你要创建一个基本的 CRUD API,我还是建议你使用 Django + DRF,或者 Rails。
原因 4:并发性&通道
Go 作为一门语言致力于使事情简单化。它并未引入很多新概念,而是聚焦于打造一门简单的语言,它使用起来异常快速并且简单。其唯一的创新之处是 goroutines 和通道。Goroutines 是 Go 面向线程的轻量级方法,而通道是 goroutines 之间通信的优先方式。
创建 Goroutines 的成本很低,只需几千个字节的额外内存,正由于此,才使得同时运行数百个甚至数千个 goroutines 成为可能。你可以借助通道实现 goroutines 之间的通信。Go 运行时间可以表示所有的复杂性。Goroutines 以及基于通道的并发性方法使其非常容易使用所有可用的 CPU 内核,并处理并发的 IO——所有不带有复杂的开发。相较于 Python/Java,在一个 goroutine 上运行一个函数需要最小的样板代码。你只需使用关键词「go」添加函数调用:
package mainimport("fmt"
"time")func say(s string) {fori :=0; i <5; i++ { time. Sleep (100* time. Millisecond) fmt. Println (s) }}func main() { go say("world") say("hello")}
Go 的并发性方法非常容易上手,相较于 Node 也很有趣;在 Node 中,开发者必须密切关注异步代码的处理。
并发性的另一个优质特性是竞赛检测器,这使其很容易弄清楚异步代码中是否存在竞态条件。下面是一些上手 Go 和通道的很好的资源:
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
原因 5:快速的编译时间
当前我们使用 Go 编写的最大微服务的编译时间只需 6 秒。相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是一个主要的效率优势。我热爱击剑,但是当我依然记得代码应该做什么之时,事情已经完成就更好了。
Go 之前的代码编译
原因 6:打造团队的能力
首先,最明显的一点是:Go 的开发者远没有 C++和 Java 等旧语言多。据知,有 38% 的开发者了解 Java,19.3% 的开发者了解 C++,只有 4.6% 的开发者知道 Go。GitHub 数据表明了相似的趋势:相较于 Erlang、Scala 和 Elixir,Go 更为流行,但是相较于 Java 和 C++ 就不是了。
幸运的是 Go 非常简单,且易于学习。它只提供了基本功能而没有多余。Go 引入的新概念是「defer」声明,以及内置的带有 goroutines 和通道的并发性管理。正是由于 Go 的简单性,任何的 Python、Elixir、C++、Scala 或者 Java 开发者皆可在一月内组建成一个高效的 Go 团队。
原因 7:强大的生态系统
对我们这么大小的团队(大约 20 人)而言,生态系统很重要。如果你需要重做每块功能,那就无法为客户创造收益了。Go 有着强大的工具支持,面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 的稳定的库。
Go 的生态系统相比于 Rust、Elixir 这样的语言有很大的优势。当然,它又略逊于 Java、Python 或 Node 这样的语言,但它很稳定,而且你会发现在很多基础需求上,已经有高质量的文件包可用了。
原因 8:GOFMT,强制代码格式
Gofmt 是一种强大的命令行功能,内建在 Go 的编译器中来规定代码的格式。从功能上看,它类似于 Python 的 autopep8。格式一致很重要,但实际的格式标准并不总是非常重要。Gofmt 用一种官方的形式规格代码,避免了不必要的讨论。
原因 9:gRPC 和 Protocol Buffers
Go 语言对 protocol buffers 和 gRPC 有一流的支持。这两个工具能一起友好地工作以构建需要通过 RPC 进行通信的微服务器(microservices)。我们只需要写一个清单(manifest)就能定义 RPC 调用发生的情况和参数,然后从该清单将自动生成服务器和客户端代码。这样产生代码不仅快速,同时网络占用也非常少。
从相同的清单,我们可以从不同的语言生成客户端代码,例如 C++、Java、Python 和 Ruby。因此内部通信的 RESET 端点不会产生分歧,我们每次也就需要编写几乎相同的客户端和服务器代码。
使用 Go 语言的缺点
缺点 1:缺少框架
Go 语言没有一个主要的框架,如 Ruby 的 Rails 框架、Python 的 Django 框架或 PHP 的 Laravel。这是 Go 语言社区激烈讨论的问题,因为许多人认为我们不应该从使用框架开始。在很多案例情况中确实如此,但如果只是希望构建一个简单的 CRUD API,那么使用 Django/DJRF、Rails Laravel 或 Phoenix 将简单地多。
缺点 2:错误处理
Go 语言通过函数和预期的调用代码简单地返回错误(或返回调用堆栈)而帮助开发者处理编译报错。虽然这种方法是有效的,但很容易丢失错误发生的范围,因此我们也很难向用户提供有意义的错误信息。错误包(errors package)可以允许我们添加返回错误的上下文和堆栈追踪而解决该问题。
另一个问题是我们可能会忘记处理报错。诸如 errcheck 和 megacheck 等静态分析工具可以避免出现这些失误。虽然这些解决方案十分有效,但可能并不是那么正确的方法。
缺点 3:软件包管理
Go 语言的软件包管理绝对不是完美的。默认情况下,它没有办法制定特定版本的依赖库,也无法创建可复写的 builds。相比之下 Python、Node 和 Ruby 都有更好的软件包管理系统。然而通过正确的工具,Go 语言的软件包管理也可以表现得不错。
我们可以使用 Dep 来管理依赖项,它也能指定特定的软件包版本。除此之外,我们还可以使用一个名为 VirtualGo 的开源工具,它能轻松地管理 Go 语言编写的多个项目。
Python vs Go
我们实施的一个有趣实验是用 Python 写排名 feed,然后用 Go 改写。看下面这种排序方法的示例:
{"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"}
Python 和 Go 代码都需要以下要求从而支持上面的排序方法:
解析得分的表达。在此示例中,我们想要把 simple_gauss(time)*popularity 字符串转变为一种函数,能够把 activity 作为输入然后给出得分作为输出。
在 JSON config 上创建部分函数。例如,我们想要「simple_gauss」调用「decay_gauss」,且带有的键值对为"scale": "5d"、"offset": "1d"、"decay": "0.3"。
解析「defaults」配置,便于某个领域没有明确定义的情况下有所反馈。
从 step1 开始使用函数,为 feed 中的所有 activity 打分。
开发 Python 版本排序代码大约需要 3 天,包括写代码、测试和建立文档。接下来,我么花费大约 2 周的时间优化代码。其中一个优化是把得分表达 simple_gauss(time)*popularity 转译进一个抽象语法树。我们也实现了 caching logic,之后会预先计算每次的得分。
相比之下,开发 Go 版本的代码需要 4 天,但之后不需要更多的优化。所以虽然最初的开发上 Python 更快,但 Go 最终需要的工作量更少。此外,Go 代码要比高度优化的 python 代码快了 40 多倍。
以上只是我们转向 Go 所体验到的一种好处。当然,也不能这么做比较:
该排序代码是我用 Go 写的第一个项目;
Go 代码是在 Python 代码之后写的,所以提前理解了该案例;
Go 的表达解析库质量优越。
Elixir vs Go
我们评估的另一种语言是 Elixir。Elixir 建立在 Erlang 虚拟机上。这是一种迷人的语言,我们之所以想到它是因为我们组员中有一个在 Erlang 上非常有经验。
在使用案例中,我们观察到 Go 的原始性能更好。Go 和 Elixir 都能很好地处理数千条并行需求,然而,如果是单独的要求,Go 实际上更快。相对于 Elixir,我们选择 Go 的另一个原因是生态系统。在我们需求的组件上,Go 的库更为成熟。在很多案例中,Elixir 库不适合产品使用。同时,也很难找到/训练同样使用 Elixir 的开发者。
结论
Go 是一种非常高效的语言,高度支持并发性。同时,它也像 C++和 Java 一样快。虽然相比于 Python 和 Ruby,使用 Go 建立东西需要更多的时间,但在后续的代码优化上可以节省大量时间。在 Stream,我们有个小型开发团队为 2 亿终端用户提供 feed 流。对新手开发者而言,Go 结合了强大的生态系统、易于上手,也有超快的表现、高度支持并发性,富有成效的编程环境使它成为了一种好的选择。Stream 仍旧使用 Python 做个性化 feed,但所有性能密集型的代码将会用 Go 来编写。
来源:机器之心
作者:Thierry Schellenbach,机器之心编译,参与:黄小天、李亚洲
原文地址:https://getstream.io/blog/switched-python-go/
“决胜2018”量化投资实战高级训练营
量化投资概述
事件驱动策略研究方法
分级基金策略
事件驱动选股
高频数据选股
期货策略的特点和独特优势……
2017年12月16日-17日上海返回搜狐,查看更多
责任编辑:
python语言的生态库都是官方开发的_放弃Python转向Go语言:我们找到了以下9大理由...相关推荐
- 在python中函数和类都属于可调用对象_在Python中函数和类都属于可调用对象
根据空气流动的动力不同,通气方式可分为()两种. 常见往复泵的排出压力低,是何原因? 影响定价的因素主要包括定价目标.产品成本.市场需求和竞争者等四个因素. 什么是排水系统? 用质量为0.25kg的锤 ...
- Python wxpython篇 | Python生态库之图形用户界面开发库 “wxPython “ 的安装及使用(附. 使用pyinstaller 库打包Python随机点名小程序程序.exe文件)
全文目录 wxPython 图形用户界面 PyCharm 中安装 wxPython库 PyCharm中将程序打包成 .exe 可执行文件 wxPython 的使用 第一个wxPython 程序 自定义 ...
- 放弃Python转向Go语言:我们找到了以下9大理由
转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时.今年 Stream 团队的主要编程语言从 Python 转向了 Go.本文解释了其背后的九大原因以及如何做好这一转换. 为什么 ...
- python所有for循环语句都可以用while改写_所有for循环语句都可以用while循环语句改写。...
[判断题]Python使用缩进来体现代码之间的逻辑关系. (1.0分) [判断题]所有for循环语句都可以用while循环语句改写. (1.0分) [简答题]编写程序,计算并输出 1~100间所有奇数 ...
- python推荐书-每一页都是干货,这10本Python新书,我必须推荐给你
大家好,我是达摩院扫地僧,今天给大家带来10本Python新书,每一本都是干货满满不可错过. 1 Python 快速入门(第3版) 书名:<Python 快速入门(第3版)> 作者: [美 ...
- python 抓取网页 库_5种流行的Web抓取Python库,你用过哪种?
"我们有足够的数据"这句话,在数据科学领域并不存在. 我很少会听到有人拒绝为他们的机器学习或深度学习项目收集更多的数据,往往都是永远觉得自己拥有的数据不够多. 为了缓解这种&quo ...
- iospython开发工具_使用Python开发iOS程序
们见过使用JS.Lua.Ruby开发iOS程序的,但是基本没有见过使用Python开发iOS程序(软件)的,这是为什么?关于这个问题,我后面会回答. 那么,怎么用Python开发iOS程序呢?其实我们 ...
- python开发职位_【python开发岗位职责|python开发是做什么的】-看准网
发展历程 自从2世纪9年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程. Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Gu ...
- python爬取百度贴吧中的所有邮箱_使用 Python 编写多线程爬虫抓取百度贴吧邮箱与手机号...
原标题:使用 Python 编写多线程爬虫抓取百度贴吧邮箱与手机号 不知道大家过年都是怎么过的,反正栏主是在家睡了一天,醒来的时候登QQ发现有人找我要一份贴吧爬虫的源代码,想起之前练手的时候写过一个抓 ...
最新文章
- 代码即财富之我学Java对象序列化与反序列化(2)
- python3 读取txt替换、n_从Python2迁移到Python3实战(一) pyupgrade
- 有勇气的牛排 --- 大数据
- python调用通达信函数_python获取通达信基本数据源码
- kali php 装mongodb,Linux系统如何安装mongodb数据库Mongo扩展
- MySQL之架构与历史(二)
- zbrush 添加纹理贴图_想学习3D游戏模型,3Dmax、MAYA和ZBrush都需要掌握吗?
- C++之继承探究(八):动态绑定
- 索尼高清影视技术学院参观观后感
- 【BZOJ 1497】 [NOI2006]最大获利
- oracle迁移至ASM磁盘
- 利用DataGrid的超级联接传值
- EF学习笔记-2 EF之支持复杂类型的实现
- 发送ajax的get请求,AJAX之发送GET请求
- ps出现标尺的快捷键,隐藏参考线,把隐藏的参考线显示出来的快捷键。
- 分享一种快速制作二维码标签及防伪溯源二维码的方法
- 微软Windows 8 非常实用的12个技巧
- 《爬楼梯》算法日记 2021.7.22,每天一道算法题,怒刷Leetcode,未做出,看评论思路后得出解。
- 用于Chrome的前端开发插件
- 计算机应用基础模拟试卷 一,计算机应用基础模拟试卷一模拟试卷-02answer