高效遍历多维数组需遵循行优先存储特性:外层循环控制行、内层控制列,使内存访问连续,提升缓存命中率。

多维数组要真正“缓存友好”,核心不是写法多酷,而是让 CPU 缓存行尽量少换、数据尽量成片加载。关键在两点:内存布局是连续的,访问顺序要贴着这个布局走。
按行优先顺序遍历(主流语言通用)
绝大多数语言(C/C++、Go、Java、Python 的 NumPy)采用行优先存储:同一行的元素在内存里挨着,跨行则跳一大段。所以外层循环控制行、内层控制列,才能保证每次读取的下一个元素大概率已在缓存中。
- ✅ 推荐写法(高效):for i := 0; i
- ❌ 避免写法(缓存不友好):for j := 0; j —— 这样每次取的是不同行的同一列,内存地址跳跃大,缓存行反复失效
提前缓存子数组引用,减少重复寻址
尤其在 Go 或 Java 等支持“数组切片”或“引用数组”的语言中,嵌套 range 容易导致每次内层循环都重新解引用外层数组。把当前行提取为局部变量,可避免重复计算地址和指针解引。
- 例如 Go 中:for i := 0; i
- 比 for _, row := range matrix { for _, v := range row { process(v) } } 更快,实测可提速一倍以上(458ms → 213ms)
确保底层内存真正连续
语法像二维,不等于物理连续。Java 的 int[][]、Go 的 [][]int、Python 原生 list[list[int]] 实际是“指针数组”,每行单独分配,彼此地址不相关。这种结构天生缓存不友好,频繁跨行访问时 cache miss 高发。
- 高性能场景应优先用连续结构:C 的
int arr[100][100]、NumPy 的ndarray、或手动申请一整块内存 + 行指针模拟 - 若必须用嵌套引用结构,且需行列切换频繁,建议预先转置,或改用单维数组 + 手动下标计算:
matrix[i * cols + j]
注意缓存行大小,对齐访问节奏
CPU 缓存一次加载通常 64 字节(一个缓存行)。假设 int 占 4 字节,一行能塞进 16 个元素。如果内层循环步长过大(如每次加 32),就容易跳过已加载的缓存行,造成浪费。
- 保持内层循环步长为 1(顺序访问)是最稳妥的
- 结构体数组中,字段排列也影响缓存效率:把高频访问字段放前面,避免为读一个 int 而加载整个未对齐结构











