这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天✌
一、本堂课重点内容:
- Benchmark
- slice优化建议
- map优化建议
- 字符串处理优化建议
二、详细知识点介绍:
以下方法通过Golang自带的Benchmark测试性能,命令是go test -bench=. -benchmem
Benchmark结果有五个值,第一个是BenchmarkXxx-N,其中Xxx为测试函数名,N为GOMAXPROCES的值,也就是Golang中GMP模型的P,用来执行处理协程,记录协程的必要信息,每一个协程都要有一个P,可以看成是协程的CPU,在Golang1.5版本以后,默认值为CPU核心数。
第二个值为测试一共执行了几次,第三个值为每次花费的时间,第四个值为每次申请了多大的内存,第五个值为每次执行申请了几次内存。
slice优化建议
- 在使用make()初始化切片时,最好指定容量信息。因为切片的本质是一个数组,包括数组的指针,长度,以及容量capacity,如果不指定容量,初始容量可能比较小,就会涉及多次扩容操作,影响性能。
- 在原切片中取小切片时,最好用copy函数,copy到一个新的切片。这是因为在切片的基础上创建切片不会创建新的底层数组,其实小切片的大小跟大切片一样(因为底层数组一样)
map优化建议
- 在使用make()初始化map时,最好指定容量信息。因为向map中添加元素可能会触发扩容,map的扩容比较复杂可能还会涉及rehash,扩容时还要进行内存拷贝。
字符串处理优化建议
-
在拼接字符串时,最好使用string.Builder,使用 + 拼接性能最差,bytes.Buffer稍慢于string.Builder。原因是每次使用 + 都会重新新建一个字符串分配内存,而string.Builder和bytes.Buffer都有底层的内存扩容策略,不用每次都要新建内存。bytes.Buffer稍慢于string.Builder的原因是:bytes.Buffer转换为字符串时重新申请了一块空间,但string.Builder只是将[]byte强制转换为string类型返回
-
map的value可设置为空结构体来实现set
三、课后个人总结:
通过以上例子我们能知道,性能优化涉及到很多Golang底层的问题如扩容等,所以能够进行性能的前提是熟悉底层结构,以及原理,所以学好底层原理十分重要。
四、引用参考:
主要参考字节跳动青训营课程juejin.cn/course/byte…