33

假设我想将 的二维矩阵表示int为向量的向量:

std::vector<std::vector<int> > myVec;

内部尺寸是恒定的,例如 5,外部尺寸小于或等于N。为了尽量减少重新分配,我想保留空间:

myVec.reserve(N);

假设内部向量的大小是多少?这纯粹依赖于实现吗?这对数据的空间局部性有何影响?由于内部尺寸是一个常数,有没有办法告诉编译器使用这个常数大小?如果内部向量的大小发生变化,这些答案将如何变化?

4

3 回答 3

20

因为你的内在维度是恒定的,我想你想要

std::vector< std::array<int, 5> > vecs;
vecs.reserve(N);

这将为您提供预分配的连续存储,这是性能的最佳选择。

于 2013-09-24T21:20:17.730 回答
14

内部向量的大小与调整外部向量的大小完全无关。您的向量包没有局部性保证,局部性保证(即内存中的连续块)仅适用于单个向量。

请记住,向量对象本身具有恒定sizeof大小,其实际数据通常是动态分配的。外向量,第一次近似,是 N 个指向内向量的“指针”的连续块。您的reserve调用不会为内部向量的可能元素保留内存,而只会为内部向量对象本身(即它们的簿记数据及其指向动态分配的数据块的指针)保留内存。

于 2013-09-24T20:51:16.043 回答
13

内部向量使用默认构造函数初始化。所以如果你写:

vector<vector<int> > vecs;
vecs.reserve(10);

这相当于调用每个元素的构造函数vector<int>vector<int>()。这意味着您将拥有一个零大小的向量。但是请记住,除非您调整(而不是保留)向量的大小,否则您不能使用它们。

还要记住,有时使用您需要的初始大小调整大小可能会更有效。所以做类似的事情很有用

vector<vector<int> > vecs(3,vector<int>(5));

这将创建一个大小为 3 的向量,每个元素将包含一个大小为 5 的向量。

还要记住,如果您要经常调整向量的大小,使用双端队列而不是向量可能更有效。它们易于使用(作为向量)并且您不需要保留,因为元素在内存中不连续。

于 2013-09-24T21:02:43.047 回答