首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有人说 Go 语言性能不行,大佬不服,使用 pprof 三步优化代码,性能堪比 C++

有人说 Go 语言性能不行,大佬不服,使用 pprof 三步优化代码,性能堪比 C++

作者头像
LIYI
发布2019-11-19 14:33:54
2.5K0
发布2019-11-19 14:33:54
举报
文章被收录于专栏:艺述论专栏艺述论专栏

这篇文章部分转自:https://www.cnblogs.com/qcrao-2018/p/11832732.html

目录

1,CPU 优化

2,内存优化

3,GC 优化

4,小结


这篇文章讲了一个故事,大意是 Go 语言大佬 Russ Cox 发现一篇文章说使用 Go 写的算法很慢,而 C++ 很快。大佬哪受得了这个,于是使用 Go 语言性能优化神器 pprof,开始了优化实战。最终经过三轮优化,基本上能达到和 C++ 同等的速度和同样的内存消耗。这三轮优化十分具有借签与学习之意义,简述如下:

1,CPU 优化

首先,使用如下代码开启 CPU 监测:

pprof.StartCPUProfile(f)

耗时 top5 的函数,发现一个读 map 的函数耗时最长:mapaccess1_fast64,而它出现在一个递归函数中。执行 web mapaccess1 命令,聚焦出调用 mapaccess1_fast64 函数最多的就是 main.FindLoops 和 main.DFS,再执行命令:list DFS,定位到相关的具体代码。

优化的方法是将 map 改成 slice。当然并不是所有的map都需要这样做,在这个案例中能这样做,和 key 的类型是 int 而且不是太稀疏有关。具体问题需要具体分析,这正是 pprof 工具的价值所在。

修改完之后,再次通过 cpu profiling,发现递归函数 mapaccess1_fast64 的耗时已经不在 top5 中了,但是新增了长耗时函数:runtime.mallocgc,占比 54.2%,而这和内存分配以及垃圾回收相关。

2,内存优化

使用如下代码开启内存监测:

FindHavlakLoops(cfgraph, lsgraph)
f,_ := os.Create(*memprofile)
pprof.WriteHeapProfile(f)

继续通过 top5、list 命令找到内存分配最多的代码位置,发现这回是向 map 里插入元素使用的内存比较多。

改进方式同样是用 slice 代替 map。但 map 有一个缺点,就是可以重复插入元素,因此写一个向 slice 插入元素的函数,可以防止重复插入:

func appendUnique(a []int, x int) []int {
    for _, y := range a {
        if x == y {
            return a
        }
    }
    return append(a, x)
}

好了,现在程序比最初的时候快了 2.1 倍。再次查看 cpu profile 数据,发现 runtime.mallocgc 降了一些,但仍然占比 50.9%。因此需要查看垃圾回收到底在回收哪些内容,这些内容就是导致频繁垃圾回收的“罪魁祸首”。

3,GC 优化

使用 web mallocgc 命令,将和 mallocgc 相关的函数用矢量图的方式展现出来,但是有太多样本量很少的节点影响观察,增加过滤命令:

go tool pprof --nodefraction=0.1 profile

在这条指令中,将少于 10% 的采样点过滤掉。

(注:这是 pprof 生成的分析结果)

新的矢量图可以直观地看出,FindLoops 触发了最多的垃圾回收操作。继续使用命令 list FindLoops 直接找到代码的位置。原来,每次执行 FindLoops 函数时,都要 make 一些临时变量,这会加重垃圾回收器的负担。

改进方式是增加一个全局变量 cache,这样可以重复利用。虽然这样做的坏处是,线程不是安全的了。

4,小结

使用 pprof 工具进行的优化到这就结束了。最后值得提一下,大佬做这件事的时间比较久远,最初写于 2011 年,原文在这里:

https://blog.golang.org/profiling-go-programs

(Russ Cox 优化过程,并附上代码)

原文有更多内容和参考资料,如果有时间推荐查看。

pprof 的包路径是 "runtime/pprof",可以通用报告生成、Web 可视化界面、交互式终端 三种方式来使用。具体使用方法可查相关文档。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档