泛型是双刃剑?Go1.18 编译会慢近 20%

大家好,我是煎鱼。

目前 Go 的泛型已经在稳定推进的过程,在 Go1.18 将会释出正式的第一版。不过前两天我看到 @danscales 提出的《cmd/compile: Go 1.18 compile time may be about 18% slower than Go.17 (largely from changes due to generics)》。

作者表示在 Go1.18 有了泛型后,编译速度可能会变慢,虽然不意外,说明泛型的副作用还是有的,大家后续升级需谨慎。

以下为修整后概括的原文信息。

性能分析

这个测试主要是测试 Go 泛型对 Go 编译器带来的影响,并没有输入大量的测试用例,是最简单的比较,仅代表大部分的差异。

比较的内容是 Go 泛型的 -G=0 和 -G=3 模式下的编译时间。

分别代表以下含义:

  • -G=0 模式:默认不打开泛型的模式。

  • -G=3 模式:打开泛型的模式。

Go 1.18 中的 -G=0 模式和 Go 1.17 模式的比较显示,由于非泛型的变化,编译器的速度可能降低了~1%(因为 -G=0 模式不支持泛型)。

Go 1.18 的编译时间可能比 Go 1.17 慢 15-18%,这主要是由于实现泛型所带来的变化,也就是 Go1.18 开启泛型下,编译时间会变慢。

差异在哪

大部分的差异是由于新的编译器前端处理,因为 SSA 后端对于泛型完全没有变化。

  • 在 -G=0 模式下(用于 Go 1.18 之前的所有编译器):有一个语法分析器,创建 ir.Node 节点树的 noder 阶段,以及标准类型检查器。

  • 在 -G=3 模式下:有相同的语法分析器,但程序首先由 types2(支持泛型)进行类型检查。

在通过 -G=3 模式打开泛型后,会有一个 noder2 阶段,使用语法信息和 types2 类型检查器的类型信息创建 ir.Node 节点树。

在一次运行中,noder+ types1-typechecking 的开销总和约为 4%,而 types2-typechecker+noder2 的总和为 14%。

经过分析,可以得到大部分的速度下降是由于改变了编译前端处理(并不意外)。

总结

可以明确的是,在打开泛型后,Go1.18 编译时间可能会慢 15-18%,Go 官方将计划在 Go 1.19 中减少这种额外的开销。所以已经不是 “可能”,是必然了。

泛型的双刃剑初见,后续不管是编译时间、执行时间(预计不会减缓)、泛型的滥用、最佳实践等,都值得我们去讨论和关注。

看来引入泛型后要经历一轮修整了,毕竟 Go 语言是以编译速度快著称...欢迎大家在评论区讨论和交流:)

关注煎鱼,吸取他的知识 👇

b807f66ed0a3c27bf0e3ffaad229ff8d.png

21fa62285e4f08409fd41520807fd73a.png

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值