聊聊五年来,我从 GO 中认识到的除了语法之外的东西

我刚开始接触 Go,还是在 1.11 版本。在这个版本,Go 刚开始引入 Go Module。不知道还有多少人记得 GO111MODULE 这个环境变量。

时至我写下这些文字,Go 已经发布到了 1.22 版本。按一年两个版本算,应该已经 5 个年头有余。在这么多年里,Go 的语法基本没什么变化,尤其是在 1.18 加入泛型之前。以至于只要讨论到语法简陋,必然有 Go 的一席之地。

但是有趣的是,简陋的语法不妨碍 Go 的流行。抛开野鸡榜单 TIOBE 不说,在 Github 的 2023 年度开源报告中,最流行的语言、最受欢迎的语言、增长最快的语言都能看到 Go 的身影。反观 JVM 阵营这边,以语法强大的著称的 Scala 日渐式微,倒是不那么激进的 Kotlin 还保持不温不火。

我不想论证什么大道至简,只是觉得不应该把目光局限在语法上,不应该为了选 try catch 还是 if err 之类的问题争论不休。反而是语法之外那些不怎么直观的东西,往往决定了一个编程语言的使用场景和前(钱)景,这才是对开发者更加重要的东西。

所以,进入正题,抛开 if err != nil ,总结一下我对 Go 的认识。

性能如何

Runtime + GC 的形态决定了 Go 语言的性能潜力应该低于无 GC 语言,并且高于带 GC 的虚拟机/解释器语言。一个最基本的道理是,A可以避免的开销,B可以避免,A避免不了的开销B也可以避免,那么在同等程度的优化下,A 没道理比 B 性能好。

但是在 AOT 技术出现后,解释型语言还是拉近了差距。不过不是原生的东西,总归会有些坑。另外编译型语言的优化也不是停滞不前的,Go 已经开始使用 PGO 编译优化,简单来说是收集运行时信息来发现更多可以优化的点。

可以说,Go 目前性能不错,并且有在 GC 语言中保持性能领先的潜力。非 GC 语言就不说了,付出更多的心智,获得更高的上限,这是公平的。

从安装到运行

go getgo rungo testgo buildgo install。安装一个几十MB的安装包,然后基本就有了开发所需要的所有东西。这些除了写代码之外的事情,Go 的体验不能说多优秀,但架不住同行衬托。

Java 还要学 maven,写一堆 xml,PHP 部署总是一堆坑,Javascript 的 node_module 像个黑洞,Python 呢,大一点的项目都得建个虚拟环境,C++ 硬是最近才开始引入包管理。哪怕是 Rust,也有包名容易被抢注,以及项目占用空间大的问题。

Go 也有语义化版本 V2 的问题,一定程度上造成了混乱。但出现频率不高,并且还算容易解决。

另外由于 Go 是编译型语言,在保护源码时也不必像 Python 一样操心,交付客户也基本不用担心运行环境。

云原生之变

很多人说 Go 能火是因为云原生,但云原生是什么,恐怕没人说的清楚,当然也包括我。但是切出一个片面来讲还是很简单的,比如说资源利用方式。

在以前,服务器资源是相对固定的,用不完也是浪费。但是云原生把资源变成了一个池子,想用多少用多少。在这种情况下,单个服务的的每一点资源使用率都能反映到成本上。打个比方,原来是给每个人发一瓶矿泉水,现在是让人自己用水杯接水,用多少算多少钱。人越多,差异越明显。

因此,虚拟机、解释器所带来的额外开销虽然不多,但是在规模效应下,也足以带来改变。

不光如此,想用多少用多少还体现在动态扩缩容。qps 高了就多用点资源,低了就少用点,如果程序如果可以更快的启动并达到可用状态,就越能及时响应需求的变化。

正是因为 Go 的低内存占用不错的性能飞快的启动速度契合云原生更精细的资源利用方式,才有资格站在风口上。

当然,Go 也不能算是版本之子,协程带来的多核利用能力,在计算密集型场景下的优势其实是被削弱了。多核利用率上不去,没关系,多起几个服务,负载均衡一下就完事了。

吐槽

在这几年使用 Go 的过程中,还是有不少想吐槽的。一是 GC 虽然暂停时间短,但吞吐量还是低了点,在极端情况下会因为来不及回收造成 OOM。后面有了 GOMEMLIMIT,才缓解了问题。

还有插件系统,虽然有,但是不好用。CGO 应该也有不少可以优化的空间。

这些吐槽都是非语法层面的,语法层面的也有,就不在这里说了。

One more thing

所谓实践出真知,知行合一永不过时。很多体会心得都来自我正在写的一个任务流编排项目:OGraph https://github.com/symphony09/ograph。对标同类C++优秀项目 CGraph。后续再结合这个项目再分享一下 Go 与 C++ 的异同,这里先打个广告,求求 star。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 13

给大佬提个建议: symphony09/ograph 更改一下包名。不喜欢这种字母与数字混用,纯属个人癖好。哈哈

1个月前 评论
腹肌会有的 1个月前

还是铺阿七铺最简单的,go还是往后靠一靠吧。

1个月前 评论

学够浪只会浪费时间和生命,还是铺阿七铺好

1个月前 评论
don178 1个月前
pu_a_qi_pu (作者) 1个月前
赵昊 1个月前
pu_a_qi_pu (作者) 1个月前
yourself

好奇是什么代码来不及回收造成 OOM呢?

1个月前 评论
symphony09 (楼主) 1个月前
yourself

是用了什么包吗?encoding/json Sonic 这种都会遇到这个问题???

1个月前 评论
symphony09 (楼主) 3周前
yourself (作者) 3周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!