优化
go 优化
- 注重锁的使用,尽量做到锁变量而不要锁过程 ,可以使用CAS机制,则使用CAS操作
- 针对热点代码要做针对性优化
- 不要忽略 GC 的影响,尤其是高性能低延迟的服务,使用对象池,声明切片定义容量
- 尽量避免反射,在高性能服务中杜绝反射的使用
- 有些情况下可以尝试调优“GOGC”参数
- 新版本稳定的前提下,尽量升级新的 Go 版本
- 对频繁分配的小对象,使用 sync.Pool 对象池避免分配
- 自动化的 DeepCopy 是非常耗时的,其中涉及到反射,内存分配,容器(如 map)扩展等,大概比手动拷贝慢一个数量级
- 在开发环境开启 net/http/pprof,方便实时 pprof
- 将所有外部IO(网络IO,磁盘IO)做成异步
参数化分析
- -gcflags=-m :查看编译器的逃逸分析和内联决定
- GODEBUG=gctrace=1 :开启gc跟踪
具体优化
- string与byte的转化,会在底层发生内存拷贝,直接修改指针
func Str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0],x[1],x[1]}
return*(*[]byte)(unsafe.Pointer(&h))
}
func Bytes2str(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
- map 会按需扩张,但须付出数据拷贝和重新哈希成本。如有可能,应尽可能预设足够容量空间,避免此类行为发生
m := make(map[string]int,10)
- 对于小对象,直接将数据交由 map 保存,远比用指针高效。这不但减少了堆内存分配,关键还在于垃圾回收器不会扫描非指针类型 key/value 对象
m := make(map[string]int,10) //值数据
m := make(map[string]*int,10) //指针数据
-
对于map类型,delete不会减少内存占用,只有将map至为nil才会释放内存
-
defer尽量少写或者合并,defer会注册延迟调用函数,影响性能
-
闭包会导致变量逃逸到堆上,造成GC负担,同时闭包会增加开销
-
对于压力很大的内部组件之间,用接口有些得不偿失,普通调用用内联