第六次笔记|青训营

63 阅读2分钟

一、性能调优实战(简介、pprof实战、性能调优案例)

性能优化建议:性能优化的前提是满足正确可靠、简洁清晰等质量因素;性能优化是综合评估,有时候时间效率和空间效率可能对立;针对go语言特性,介绍go相关的性能优化建议

Benchmark:如何使用:性能表现需要实际数据衡量;go语言提供了支持基准性能测试benchmark工具——结果解释

Slice:预分配内存——尽可能在使用make()初始化切片时提供容量信息

切片本质是一个数组片段的描述:包括数组指针、片段的长度、片段的容量(不改变内存分配情况下的最大长度);切片操作并不复制切片指向的元素;创建一个新的切片会复用原来切片的底层数组;

另一个陷阱:大内存未释放:在已有切片基础上创建切片,不会创建新的切片数组

用copy替代re-slice   (原切片较大等等)

Map预分配内存:不断向map添加元素的操作会触发map的扩容,提前预分配内存能够提高性能

字符串处理:使用string.builder 将三种字符串处理函数相比较

字符串在go语言中是不可变类型,占用内存大小固定;使用+每次都会重新分配内存;string.builder,bytes.buffer底层都是[]byte数组;内存扩容策略,不需要每次拼接重新分配内存

实际上有时候使用string.builder时将底层的[]byte转换成了字符串类型返回,在此基础上如果能够加入内存预分配的操作,能够进一步提高性能

空结构体:使用空结构体节省内存——空结构体struct{}实例不占据任何的内存空间

可作为各种场景下的占位符使用:节省资源、空结构体本身具备很强的语义,即这里不需要任何值,仅作为占位符

实现set,可考虑用map代替

Atomic包:锁的实现是通过操作系统来实现,属于系统调用;atomic操作通过硬件实现,效率比锁高;sync.mutex应该用来保护一段逻辑,不仅仅用于保护一个变量;对于非数值操作,可以使用atomic.value,能承载一个interface{}

小结:避免常见的性能陷阱可以保证大部分程序的性能;普通应用代码,不要一味的追求程序的性能;越高级的性能优化手段越容易出问题;在满足正确可靠、简洁清晰的要求的前提下提高程序性能

性能优化分析工具:性能调优原则:要依靠数据而不是猜测;要定位最大瓶颈而不是细枝末节;不要过早、过度优化。