行遍历通常更快,前提是语言采用行优先存储(如Java、C/C++)且数组规模足够大;小数组差异微乎其微,JS因内存不连续而表现不同。

行遍历通常比列遍历更快,但这个结论依赖于底层存储方式和数据规模——不是绝对的,而是有明确前提的。
行优先存储是关键前提
Java、C、C++等语言中,二维数组在内存里按“行优先”(row-major)顺序连续存放:第一行所有元素排在一起,紧接着是第二行,依此类推。这意味着 arr[i][j] 和 arr[i][j+1] 地址相邻,而 arr[i][j] 与 arr[i+1][j] 之间隔着整行长度。
- 行遍历(外层i,内层j):每次内循环访问的是连续内存块,CPU缓存能一次性加载多个相邻元素,命中率高。
- 列遍历(外层j,内层i):每次访问 arr[0][j]、arr[1][j]… 实际跳转到不同行的同一列位置,地址分散,几乎每次都要触发缓存未命中。
高维数组同样适用该规律
三维数组 int[][][] data 也遵循行优先布局:最右下标变化最快。因此高效写法是:
- 最外层循环遍历 i(慢变)
- 中间层遍历 j
- 最内层遍历 k(快变)
这样保证内层每次操作都在同一片连续内存上滑动。若把k放在最外层,就人为破坏了空间局部性,维度越高,性能损失越显著。
JavaScript 是个例外
JS中的二维数组本质是数组套数组(Array of Arrays),每个子数组独立分配内存,不保证整体连续。实测显示:
- 小数组(如1万元素以内):列遍历反而略快,因V8引擎对短序列的优化更敏感;
- 大数组(超225万元素):行遍历开始反超,此时内存布局的局部性影响压倒引擎调度开销。
别忽略实际规模的影响
缓存效应只在数据远大于L1/L2缓存容量时才明显。例如:
- 一个100×100的int数组仅占40KB,在多数CPU的L2缓存(几百KB)内可全驻留,行列差异微乎其微;
- 但10000×10000数组达400MB,必然频繁换页和缓存淘汰,此时遍历顺序直接影响毫秒级延迟。
所以不是“永远要选行遍历”,而是“当数组够大且语言采用行优先存储时,优先让最内层循环步进最快变化的下标”。


















