Go程序提速42%,只需改变一个字符

2022 年 11 月 20 日 量子位
梦晨 发自 凹非寺
量子位 | 公众号 QbitAI

Go语言本来就以轻量快速著称,一位GitHub员工却偶然发现:

只改变一个字符的位置,能把一段代码运行速度提高足足42%

简直就像是……

这个简单有效的技巧一经发布,就引来众多程序员围观。

原作者自己也调侃,一般这种情况都是事先犯了个愚蠢的错误,后面才能提升这么大。

不过顺着这个思路发现有人发现,就连Go开发团队的核心人物Russ Cox都在标准库中犯过同样的错误

什么样的错误?

发现这个问题的Harry在大型程序员交友平台GitHub工作。

他在开发一个把GitHub仓库中每个文件的所有者列出来的小工具。

功能很简单,就是根据CODEOWNERS文件中定义的规则匹配,写在越下面的规则优先级越高。

原理也很简单,就是从后往前一条一条处理,匹配到了就停止。

但就是这样一个简单的程序却出现了性能问题,处理中等大小的仓库就很慢了。

他打印出火焰图,发现大部分时间都花在了Go语言的正则表达式引擎中。

另外在内存动态分配malloc垃圾回收gc上面的花费也值得注意。

要减少malloc的时间,就需要用到Go语言的逃逸分析(Escape Analysis)了。

简单来说,就是尽量把变量分配到栈上,让编译器自动管理内存的释放。

只有在“逃逸”也就是变量的作用域超出所在的栈时,才把变量分配到堆上,减轻运行时GC的压力。

在这次的程序中,Harry确定了逃逸的变量是rule这个结构体(struct)。

但问题是,rule存储在RuleSet这个切片(slice)里,按Go语言的规则可以确信他已经在堆中了。

再分析一下代码,发现在给rule赋值的时候实际上是做了一次不必要的拷贝,后面用“&”取地址时候创建了一个逃逸的指针指向它的副本。

最后解决办法也很容易想出,只需要把&移动到上面。

这样就引用了切片中的结构体,避免了拷贝。

如何彻底避免?

在热议中,有网友分享了自己是怎么避免出现这个问题的。

对于每个结构体,把它看作纯值或纯指针,压根就不去使用&这种取地址的操作,避免隐式的内存分配。

如果你想要深入理解这个问题,也有人贴心的给出了需要提前了解的一些背景知识。

最后有人指出,Rust语言为避免这个问题,直接规定必须显式操作才能拷贝一个数据结构。

当你不习惯的时候这规定烦得要命,但是总的来看还是值得。

方便or规范,你更倾向于哪种做法?

参考链接:
[1]
https://hmarr.com/blog/go-allocation-hunting/
[2]https://news.ycombinator.com/item?id=33594676

MEET 2023 大会定档!

首批嘉宾阵容公布

量子位「MEET2023智能未来大会」正式定档12月14日!

首批嘉宾包括郑纬民院士、MSRA刘铁岩、阿里贾扬清、百度段润尧、高通Ziad Asghar、小冰李笛、浪潮刘军以及中关村科金张杰等来自产学研界大咖嘉宾,更多重磅嘉宾陆续确认中。

点击“预约”按钮,一键直达大会直播现场!


点这里关注我 👇 记得标星噢 ~


一键三连「分享」、「点赞」和「在看」

科技前沿进展日日相见 ~ 


登录查看更多
0

相关内容

GitHub.com 使用 Git 作为版本控制系统(version control system)提供在线源码托管的服务,同时是个有社交功能的开发者社区。 国外类似服务: Bitbucket.com
Gitlab.com
国内类似服务:
Coding.net
【2022新书】数据可视化与Python和JavaScript,第二版
专知会员服务
77+阅读 · 2022年12月25日
【经典书】现代C语言教程,408页pdf手写教你写C代码
专知会员服务
62+阅读 · 2022年8月5日
高性能计算专家Jack Dongarra获2021年图灵奖
专知会员服务
16+阅读 · 2022年3月30日
【2020新书】C++20快速语法参考,第4版,209页pdf
专知会员服务
71+阅读 · 2020年8月5日
Python导论,476页pdf,现代Python计算
专知会员服务
259+阅读 · 2020年5月17日
Go 运行时:4 年之后
InfoQ
0+阅读 · 2022年10月17日
“如今,99.9% 以上的代码都是垃圾!”
CSDN
0+阅读 · 2022年7月19日
函数式编程中的两个棘手问题
CSDN
0+阅读 · 2022年4月24日
泛型会让你的 Go 代码运行变慢
InfoQ
0+阅读 · 2022年4月4日
「Hello World」中的「bug」
机器之心
0+阅读 · 2022年3月22日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
2+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2010年12月31日
Arxiv
0+阅读 · 2023年1月25日
Arxiv
0+阅读 · 2023年1月25日
已删除
Arxiv
32+阅读 · 2020年3月23日
Arxiv
14+阅读 · 2018年5月15日
VIP会员
相关资讯
Go 运行时:4 年之后
InfoQ
0+阅读 · 2022年10月17日
“如今,99.9% 以上的代码都是垃圾!”
CSDN
0+阅读 · 2022年7月19日
函数式编程中的两个棘手问题
CSDN
0+阅读 · 2022年4月24日
泛型会让你的 Go 代码运行变慢
InfoQ
0+阅读 · 2022年4月4日
「Hello World」中的「bug」
机器之心
0+阅读 · 2022年3月22日
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
2+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2010年12月31日
Top
微信扫码咨询专知VIP会员