首先,astd::vector<std::vector<int>>
可以有不同大小的内部向量。但是,我假设您正在专门讨论使用这种类型来模拟 2D 数组。假设您在创建向量时设置了向量的大小,您可能不需要担心动态分配的数量,因为这一切都是一次性发生的。
向量在内部分配其元素的数组。因此,外部向量分配了一个向量数组,而每个内部向量都分配了一个int
s 数组。你可以这样想:
┌─────┐
│ vec │
└──╂──┘
┃
▼
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ vec │ vec │ vec │ vec │ vec │ vec │ vec │ vec │ vec │
└──╂──┴──╂──┴──╂──┴──╂──┴──╂──┴──╂──┴──╂──┴──╂──┴──╂──┘
┃ ┗━━━━━━━━━━┓
▼ ▼
┌─────┬─────┬┄ ┌─────┬─────┬┄
│ int │ int │ │ int │ int │
└─────┴─────┴┄ └─────┴─────┴┄
如您所见,int
s 的数组彼此完全分开。它们可能位于完全不同的内存位置。这称为碎片。它们几乎肯定不会位于单个连续的内存块中。因此,跨 2D 矢量的不同“行”访问元素可能会导致缓存未命中。
但是,如果您分配 s 的单个向量int
并进行自己的二维索引,则您的内存布局更像这样:
┌─────┐
│ vec │
└──╂──┘
┃
▼
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬┄
│ int │ int │ int │ int │ int │ int │ int │ int │ int │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴┄
s现在int
存储在单个连续的内存块中。任何访问都可能具有相似的内存地址并导致缓存命中。这可能会给您带来性能提升。