迭代二维结构时,单循环遍历总长度和嵌套行列循环哪种执行速度更快?
二维范围遍历两种实现的性能对比结论
结论先行
大规模迭代场景下,嵌套循环方案的性能显著优于单循环取模计算方案,优先选择嵌套循环实现。
两种实现方案回顾
- 单循环+取模计算方案:
for (int i = 0; i < width * height; i++) { int x = i % width; int y = i / width; //Do stuff }
- 嵌套循环方案:
for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { //Do stuff } }
性能差异核心原因
- 基础运算开销差距大
单循环方案每轮迭代都需要执行整数除法和取模运算,这两类运算在CPU中属于高延迟指令:现代x86架构下,单条整数除法指令的延迟可达10~20个时钟周期,是普通加法、比较指令的几十倍。而嵌套循环的x、y变量仅需自增和边界比较,无额外高开销运算,单轮迭代的运算成本低一个数量级。 - 编译器优化支持度不同
嵌套循环是标准的二维遍历结构,主流编译器在O2及以上优化等级下,可以自动对其做循环展开、SIMD向量化、缓存预取等优化,可进一步将执行效率提升数倍。而单循环+取模的结构编译器很难识别为二维遍历模式,不仅很难触发上述优化,甚至会因为取模运算的存在完全阻断向量化优化。 - 特殊场景差距缩小但不会反超
仅当width为2的整数次幂时,编译器可能会把取模和除法运算优化为位与、位移运算,此时两者的运算开销差距会缩小,但嵌套循环的优化空间依然更大,性能不会弱于单循环方案。
额外建议
嵌套循环的可读性也远优于单循环方案,无论是性能还是可维护性角度,都没有理由选择单循环取模的实现方式。
内容的提问来源于stack exchange,提问作者Rilazy
相关产品推荐
相关产品推荐

