Go性能优化
Go用下来最深的体会就是其极其高效的性能。
官方调优工具
pprof:调优分析和可视化工具
图形化展示需要先安装graphviz,运行dot -c 命令验证安装成功。
sudo apt install graphviz
// 编程的方式展现pprof
// 支持两种类型:工具型和web服务型
// 工具型
import "runtime/pprof"
// web服务型
// 通过URL访问 /debug/pprof/
import _ "net/http/pprof"
go tool pprof --help
# 命令格式
go tool pprof -http=":8081" [binary] [profile]
# 内存的调优价值更大
go tool pprof --alloc_objects your-program mem.ppro
# CPU Profiling
go tool pprof your-program cpu.pprof
常用命令行:
- top
- tree
- web
- list funcName
go test
与pprof 结合应用。
go test bench . -cpuprofile=cpu.pprof
go test bench . -memprofile=mem.pprof
最佳实践
- 写测试和benchmarks
- protobuf/msgp优于json(用到的反射影响性能)
- strconv.Itoa 优于 fmt.Sprint
- 指定slice容量
并发相关
- 善用race detector 检查: -race
- 用atomic、sync.Map代替Mutex
I/O 和内存相关
- 善用 sync.Pool对象池,避免分配小对象(hot code的内存申请)
- 尽量避免 []byte 和string的频繁转换
- 使用strings.Build或bytes.Buffer(代替直接字符拼接)
- 善用bufio.NewWriter或bufio.NewReader
[]byte buffers
var (
// both buffers are uninitialized
dst []byte
src []byte
)
dst = append(dst, src...) // is legal if dst is nil and/or src is nil
dst = append(dst, "foobar"...) // append String
copy(dst, src) // is legal if dst is nil and/or src is nil
(string(src) == "") // is true if src is nil
(len(src) == 0) // is true if src is nil
src = src[:0] // works like a charm with nil src
// this for loop doesn't panic if src is nil
for i, ch := range src {
doSomething(i, ch)
buf := make([]byte, 100)
a := buf[:10] // len(a) == 10, cap(a) == 100.
b := a[:100] // is valid, since cap(a) == 100.
Prometheus监控
Go运行时metrics
通过golang_client收集的基础数据.
- 基本信息
- go_info
- go_threads
- go_goroutines
- 内存相关
- go_memstats_*
- go_gc_duration_seconds
- process_resident_memory_bytes
- process_virtual_memory_bytes
- 文件句柄
- process_max_fds
- process_open_fds
资源
学习资料
- Go-advice
- Uber Go Style Guide
- Golang 新手可能会踩的 50 个坑
- best practices for writing high-performance Go code
代码静态分析
测试工具
名称 | 教程 | 备注 |
---|---|---|
hey | ❤ 替代ab | |
boomer | Locust扩展 | |
Vegeta | ||
Hargo | 解析HAR文件并回放 | |
mqtt-stresser | MQTT message broker压测 |
# boomer
brew install zeromq czmq libsodium
# vegeta
echo "PUT http://127.0.0.1/user/xulz" | vegeta attack -keepalive=false -duration=60s | tee results.bin | vegeta report
第三方增强库
- FastHTTP – Fastest and reliable HTTP implementation in Go
- fiber: 基于fasthttp的类Express Web框架