梦晨 发自 凹非寺量子位 | 公众号 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赋值的时候实际上是做了一次不必要的拷贝 , 后面用“&”取地址时候创建了一个逃逸的指针指向它的副本 。
文章插图
最后解决办法也很容易想出 , 只需要把&移动到上面 。
【Go程序提速42%,只需改变一个字符】
文章插图
这样就引用了切片中的结构体 , 避免了拷贝 。
如何彻底避免?
在热议中 , 有网友分享了自己是怎么避免出现这个问题的 。
推荐阅读
- api是什么意思?
- 程序员为什么喜欢夜间工作?
- 小程序|微信招聘小程序定制开发-广州小程序开发
- 赵丽颖|赵丽颖闺蜜官宣生子!跟麦迪娜王灿住同个月子中心!42天花费30万
- 山口百惠|42年后再看这对日本“神仙眷侣”:他们的结合,治愈原生家庭的痛
- 程序员|程序员这么帅合理吗??看完陈飞宇新剧,请大家先冷静冷静
- 庭审流程十大关键步骤 庭审程序
- 如何用Code Blocks编写并运行C语言程序
- 杨丽娟|42岁张柏芝被曝怀四胎,别再骂她了
- 婚变|樊小慧婚变半月后再露面,身形变瘦笑容甜美,称已在走离婚程序