性能优化建议
- 性能优化的前提是满足正确可靠、简洁清晰等质量因素
- 性能优化是综合评估,有时候时间效率和空间效率可能对立
性能优化建议——Benchmark
课后我也去查了这个工具,这是关于Benchmark工具的一些基本信息和用法:
- 写基准测试函数: 在测试文件中,使用 func BenchmarkXxx(b *testing.B) 的格式来定义基准测试函数。这里的 Xxx 是你要测试的函数名,例如下图中的Fib10。
- 循环执行: 基准测试函数会在一个循环内运行,循环次数由测试框架自动控制。在每次循环中,被测试的代码会被执行多次。
- 计时和测量: 测试框架会测量每次循环执行的时间,并根据总执行次数计算出每次执行的平均时间。测试框架会自动选择执行次数,以确保测试结果的稳定性。
- 运行基准测试: 使用
go test -bench=命令来运行基准测试。例如,go test -bench=. -benchmem会运行所有基准测试,并显示内存分配的统计信息。 - 结果解释: 基准测试的结果会显示每次循环的平均执行时间,以及操作的每秒执行次数。此外,通过
-benchmem标志,你还可以查看内存分配的情况。
性能优化建议——Slice
- 预分配内存。在创建切片时,如果你事先知道大致的容量,可以使用
make函数预分配切片的容量。这有助于避免频繁的重新分配和复制。 - copy。大内存时用copy代替re-slice,这样可以防止掉入大内存未释放的陷阱。
性能优化建议——map
- 预分配内存。不断向map中添加元素的操作会触发map的扩容,提前分配好空间可以减少内存的拷贝和Rehash的消耗。
性能优化建议——字符串处理
- 使用strings.Builder,strings.Builder直接将底层的[]byte转换成了字符串类型返回,byte.Buffer则是重新申请了空间。所以strings.builder会更快。
性能优化建议——空结构体
- 使用空结构体节省内存。空结构实例不占据任何的内存空间,可以作为各种场景下的占位符使用。
性能优化建议——使用atomic包
- 锁的实现是通过操作系统来实现,属于系统调用。
- atomic操作是通过硬件实现,效率比锁高。
- sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量。
- 对于非数值操作,可以使用atomic.Value,能承载一个interface{}。
小结
- 避免常见的性能陷阱可以保证大部分程序的性能。
- 普通应用代码,不要一味地追求程序的性能。
- 越高级的性能优化手段越容易出现问题。
- 在满足正确可靠、简洁清晰的质量要求的前提下提高程序性能。