性能优化
slice预分配内存
- 尽可能在使用make() 初始化切片时提供容量信息
go
复制代码
func PreAlloc(size int) {
data := make([]int, 0, size)
for k := 0; k < size; k++ {
data = append(data, k)
}
}
- 在已有切片基础上创建切片,不会创建新的底层数组,所以原底层数组在内存中有引用得不到释放,可以使用copy代替原切片
go
复制代码
func GetLastBySlice(origin []int) []int {
return origin[len(origin)-2:]
}
func GetLastByCopy(origin []int) []int {
result := make([]int, 2)
copy(result, origin[len(origin)-2:])
return result
}
map预分配内存
- 尽量不使用bytes.Buffer,使用strings.Builder
空结构体
- 空结构体 struct{} 实例不占据任何的空间
- 节省资源
- 空结构体本身具备很强的语义,即这里仅作为占位符
atomic包
在多线程场景下使用该包可以保证计数器技术准确,线程安全
- atomic操作时通过硬件实现的,效率比锁高
- 对于仅仅保护一个变量,建议使用atomic包,因为sync.Mutex不仅仅保护一个变量,还用来保护一段逻辑
- 对于非数值操作,可以使用atomic.Value,能承载一个接口
pprof
用于可视化和分析性能分析数据的工具,使用它可以知道应用在什么地方耗费了多少cpu、memory等指标
使用
-
在代码中引入了nethttpprof包,会将pprof的入口注册到/debug/pprof路径下
allocs:内存分配情况
arduino
复制代码
blocks:阻塞操作情况
cmdline:显示运行进程的命令
goroutine:当前所有goroutine的堆栈信息
heap:堆上内存使用情况
mutex:锁竞争操作情况
profile:CPU占用情况
threadcreate:当前所有创建的系统线程的堆栈信息
trace:程序运行跟踪信息
-
在终端运行 go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10",等待采样数据展示到终端
-
输入top n查看cpu占用最高的函数,默认十个
从左到右依次是当前函数本身的执行耗时、flat占用cpu总时间的比例、上面每一行flat%的总和、当前函数本身加上其调用函数的总耗时、cum占cpu总时间的比例
-
输入list 正则表达式 查找代码行
-
也可以输入web 生成一张调用关系图,默认用浏览器打开
-
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"