for循环条件表达式的性能影响及两种写法的性能差异对比
Go循环写法性能差异解答
for条件表达式的求值规则
Go语言官方规范明确规定:for循环的条件表达式每次迭代前都会重新求值,不会只在循环开始前计算一次。
两种写法的性能差异
分两种场景讨论:
- 循环体中不会修改切片长度的场景
目前所有正式支持的Go版本(1.10及以上)的编译器都具备循环不变量提取优化能力,只要编译器可以确定循环过程中切片长度不会发生变化,就会自动把len(slice)的计算逻辑提取到循环外部执行,两种写法最终生成的汇编代码完全一致,不存在任何性能差异。
你可以通过go build -gcflags="-S"命令编译代码查看汇编输出,验证两种写法的执行效率完全相同。 - 循环体中会修改切片长度的场景
这种场景下两种写法的业务逻辑本身就存在差异,没有比较性能的意义:- 第一种写法每次循环都会读取切片的最新长度,如果你在循环内执行了
append、重新赋值切片等修改长度的操作,循环次数会随之变化 - 第二种写法使用的是循环开始前缓存的切片长度,后续切片长度变化不会影响循环次数
- 第一种写法每次循环都会读取切片的最新长度,如果你在循环内执行了
实际使用建议
如果你的业务逻辑要求循环次数固定为循环启动时的切片长度,提前把长度赋值给变量的写法更安全,可以避免不小心在循环内修改切片导致的预期外循环次数问题。如果逻辑要求每次循环都读取最新的切片长度,只能把len(slice)写在条件判断里。单纯从性能角度考虑,只要循环体内不会修改切片长度,两种写法没有区别,不需要刻意提前缓存长度。
内容的提问来源于stack exchange,提问作者Kolom
相关产品推荐
相关产品推荐

