08/02
2021
golang之defer性能测试
在golang编码中,各种规范都在告诉我们在释放资源的时候要使用defer,尽量的在申请完资源,立马defer资源。经典的比如lock的使用。
今天看了一个开源库的实现,发现在使用lock的时候,并没有用defer unlock,而是在每一个分支处理完成之后独立的去unlock。这样无疑比较容易出bug,但同时又让我产生了一丝好奇,使用defer和不使用defer的性能差距到底有多大呢。
写两个方法,一个使用defer,一个不使用defer。
func deferHandler(i int) {
defer func() {
i++
}()
return
}
func withoutDeferHandler(i int) {
i++
return
}
benchmark测试用例
func BenchmarkDeferHandlder(b *testing.B) {
for i := 0; i < b.N; i++ {
deferHandler(i)
}
}
func BenchmarkWithoutDeferHandlder(b *testing.B) {
for i := 0; i < b.N; i++ {
withoutDeferHandler(i)
}
}
测试结果
> go test -bench .
goos: darwin
goarch: amd64
pkg: blurty/test/benchtest
cpu: VirtualApple @ 2.50GHz
BenchmarkDeferHandlder-8 414536647 2.908 ns/op
BenchmarkWithoutDeferHandlder-8 1000000000 0.3134 ns/op
PASS
结论
可以看到,使用defer和不使用defer的性能相差10倍,正好一个数量级。
当然在业务代码里,我们基本可以放心的使用defer,毕竟3ns的耗时也可以忽略不计。毕竟在业务实现里,一个函数里,业务逻辑的操作已经远远超过3ns了。
不过在越靠近底层的基础库里,我们越需要考虑性能的话。3ns的影响也是不可忽视的,比如如果有个底层接口的调用qps是100w/s,那defer就需要耗时3ms,能优化是最好不过了。
本站总访问量次
本站访客数人次
本文总阅读量次