这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
highlight: a11y-dark
高质量编程
Go语言性能优化
性能评估Benchmark工具
go test -bench=. -benchmen
//注意bench要使用的话函数需要这么写
func BenchmarkNoPreAllox(b *testing.B) {
//设置时间
b.ResetTimer()
for i := 0; i < b.N; i++ {
NoPreAlloc(3)
}
}
slice
- 预分配
- 大内存未释放
Map
预分配
String
+最差 string.Builder bytes.Buffer 相近 strings.Builder最快
string在go中是不可变类型,使用+拼接性能最差, 每次使用+都会重新分配内存
string.Builder bytes.Buffer底层是byte数组,不需要每次拼接都扩充内存
-
bytes.Buffer:重新申请空间转string
-
string.Builder:直接转string
提前计算长度可Grow 更快
string.Builder和bytes.Buffer都有.Grow(n * len(str))
这样的话string.Builde只涉及一次内存分配
bytes.Buffer由于重新申请空间转string,需要两次内存分配
空结构体
不占有内存空间
节省空间 可以作为任何场景下的占位符
m:=make(map[int]struct{})
使用map空结构体实现set 因为set只需要map的键,值不需要,哪怕是把值设置为bool也占有一个字节的空间,所以可以考虑空结构体占位
go不内置set
多线程
eg场景:写一个计数器,可以同时多人使用
使用atomic包比使用加锁快
- atomic硬件时间,效率高
- sync.Mutex应该用来保护一段逻辑,不能仅仅用于保护一个变量
- 非数值型,使用automic.Value 承载一个interface{}
性能调优实战
工具 pprof的使用
运行起来后
- 可以看cpu
-
浏览器打开首页
localhost:6060/debug/pprof/
cpu
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
seconds=10 设置采集10s的 可以修改
接着进入pprof命令:可以输入以下命令
topN
| flat | 当前函数本身执行耗时 |
| flat% | 占cpu总时间比例 |
| sum% | 上面每一行flat%总和 |
| cum | 当前函数本身加上其调用其他函数的总耗时 |
| cun% | cum占cpu总时间比例 |
注意:
flat==cum:函数中没有调用其他函数,消耗都是本身导致的
flat==0:函数只有其他函数的调用
list Eat
Eat是因为top的第一行最后指出了耗时最长的函数
web 关系可视化
报错failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in $PATH
需要安装Graphviz
直接brew报Warning: Bottle missing, falling back to the default domain...
重装brew 更新后安装
各种错误部分如下
Error: No such file or directory
-http=:8080 可以直接在浏览器打开
heap-堆内存问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
goroutine问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
火焰图 Flame Graph
小块越长,占用cpu时间越长
火焰图是可以简单交互的
mutex-锁问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
block阻塞
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
注意在展示分析时会丢弃占比小的结点,可以在首页 localhost:6060/debug/pprof/
连接点进去看