这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天,在第五天的基础上学习了性能优化的建议
在Go语言中自带了一个包,叫test,该包包含了单元测试和性能基准测试,而性能基准测试benchmark是我们在性能优化时需要使用的工具之一
基准测试
基准测试就是在一定的工作负载之下检测程序性能的一种方法。基准测试的基本格式如下:
func BenchmarkName(b *testing.B){
// ...
}
基准测试以Benchmark为前缀,需要一个*testing.B类型的参数b,基准测试必须要执行b.N次,这样的测试才有对照性,b.N的值是系统根据实际情况去调整的,从而保证测试的稳定性。
为Split函数编写基准测试函数
func BenchmarkSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
Split("a:b:c", ":")
}
}
基准测试并不会默认执行,需要增加-bench参数,所以我们通过执行go test -bench=Split命令执行基准测试
注意: 若想运行所有基准测试函数,需要在-bench后面加上点,有两种写法,写法一:-bench=".",写法二:-bench .。不能直接-bench=.,在Windows下直接这样子写的话结果是不会运行任何基准测试的用例
6041946和194.6ns/op表示每次调用Split函数耗时194.6ns,这个结果是6041946次调用的平均值
在编写代码过程中,很多时候会使用到动态分配内存,因此需要了解部分go语言的底层原理,才能方便我们进行性能优化
slice
slice在go语言中称为切片,是一种数据结构,被用作go语言里面数组的描述符,并且切片是可以动态增长的
在go语言中,slice的底层结构如下
type slice struct {
array unsafe.Pointer
len int
cap int
}
array表示切片指向的底层数组,每个切片都会指向一个底层数组,对切片的操作本质上是对于底层数组的操作
len是当前切片中所含有元素的个数
cap是在不进行内存分配(切片扩容)的情况下,切片可以容纳最大的元素个数,cap≥len
go语言中可以使用make() 来创建一个切片,在创建时必须要指定切片的类型以及长度len。若知道cap可以提前使用cap来定义切片,为切片预分配空间,这样能达到性能优化的目的,减少程序在执行过程中重复对切片进行扩容的操作
同理,map作为一种在go中的数据结构,也是使用make()函数来进行创建,依然可以在已知map大小的情况下,在创建的时候指定map可以存放的数据大小。map和slice都能进行动态扩容