go1.13之Error Warp
本文给出使用go1.13 defer时应该避免的姿势。
性能提升30%的原理和defer本身的原理不做介绍。这两项可分别参考资料1,2,3。
资料1简单给出性能提升的一些关键点。重点是原来defer语法依赖的_defer
数据结构只能分配在堆上,新版本中可以针对性分配在栈上。免去了systemstack()或mallocgc()
带来的开销。
资料2-3详细介绍了defer原理;此原理在go1.13版本中不过时,因为go1.13的优化场景具有针对性。
简单来说,要想享受defer带来的30%性能提升。以下两种场景的代码要避免:
- defer语句外层嵌套有显式循环;
- defer语句有隐式循环;
显式循环考虑以下代码
|
|
看汇编结果,底层调用的是runtime.deferproc。还是老方式,即_defer
对象分配在堆上。
|
|
注意循环只执行一次,实际只要它有循环次数,都是在堆上分配对象。等于性能优化享受不了。
|
|
隐式循环考虑以下代码
|
|
看汇编结果,只有第一个defer底层调用runtime.deferprocStack(),_defer
对象分配在栈上。原因是第二个defer语句其实有一个隐式循环。
|
|
避免以上两种情况就能享受30%的性能优化。
最后,虽然go1.13 中defer只针对部分场景性能提升了30%,但官方issue并没有close,也是希望社区有更多的case反馈,可以更通用地提升defer的性能。
未来还是美好滴。
资料1:https://mp.weixin.qq.com/s/BzUlYL9xsqgzUDOyxqgBgw