我有一个非常大的多维向量,它的大小一直在变化。当我只知道一个很好的近似大小时,使用vector.reserve()函数有什么意义吗?
所以基本上我有一个向量A[256*256][x][y]
y值每次可以不同,这意味着对于[256*256][y]
元素中的每一个,向量y可以具有不同的大小,但是仍然小于256;
所以为了澄清我的问题,我有:
vector<vector<vector<int>>> A;
for(int i =0;i<256*256;i++){
A.push_back(vector<vector<int>>());
A[i].push_back(vector<int>());
A[i][0].push_back(SOME_VALUE);
}
将元素添加到向量...
A.clear();
在这之后,我又从头开始做同样的事情。
我应该在什么时候以及如何为向量保留空间。如果我正确理解了这一点,我会节省很多时间,如果我会使用保留,因为我改变了大小的所有时间?
在某些情况下,保留向量的最大大小([256*256][50][256]
)的负/正边是什么?
顺便说一句。我知道不同的矩阵模板和增强,但已决定去与向量对这一个...
**EDIT:**我还想知道如何在多维数组中使用reserve函数。如果我只在二维中保留向量,那么如果我在第三维中超过了它的容量,它会复制整个向量吗?
4条答案
按热度按时间epggiuax1#
为了有助于讨论,您可以考虑以下typedef:
增加
int_t
的代价只会影响这个特定向量的内容,而不会影响任何其他元素。增加mid_t
的代价需要复制该向量中所有存储的元素,也就是说,它将需要所有的int_t
向量,这是相当昂贵的。增加ext_t
的代价是巨大的:它将需要复制 * 所有 * 已经存储在容器中的元素。现在,为了提高性能,更重要的是获得正确的
ext_t
大小(在您的问题中似乎是固定的256*256),然后获得正确的中间mid_t
大小,这样代价高昂的重新分配就很少了。您所讨论的内存量非常大,因此您可能需要考虑一些不太标准的方法来解决问题。首先想到的是添加额外的间接层。如果不保存实际的向量,而是保存指向向量的智能指针,则可以减少增加
mid_t
和ext_t
向量的成本(如果ext_t
的大小是固定的,就使用一个向量mid_t
).现在,这意味着使用您的数据结构的代码将更加复杂,(或者最好添加一个负责间接寻址的 Package 器)。每个int_t
向量将在内存中分配一次,并且永远不会在mid_t
或ext_t
重新分配中移动。重新分配mid_t
的成本与分配的int_t
向量的数量成比例,而不是与插入的整数的实际数量成比例。另一件需要注意的事情是
std::vector::clear()
不会释放向量中分配的内部空间,只会破坏包含的对象并将大小设置为0。也就是说,调用clear()
永远不会释放内存。实际释放向量中分配的内存的模式是:9rygscc12#
每当您将向量推入另一个向量时,请在pushed vectors建构函式中设定大小:
yzuktlbb3#
您有一个正在工作的实现,但担心性能问题。如果您的分析显示它是一个瓶颈,您可以考虑使用一个裸C样式的整数数组,而不是向量的向量的向量。
有关示例,请参见how-do-i-work-with-dynamic-multi-dimensional-arrays-in-c
每次都可以重复使用相同的分配,根据需要进行
realloc
操作,并最终将其保持在使用率的高潮标记。如果向量确实是瓶颈,除了避免每次循环迭代对向量进行大小调整操作之外,性能可能会由您对数组的访问模式所支配。请尝试按顺序访问最高阶。
kq4fsx7k4#
如果你在构造时知道向量的大小,那么就把它传递给c 'tor,然后用
operator[]
而不是push_back
赋值。如果你不确定最终的大小,那么就猜测一下(可能会多加一点),然后用reserve
让向量预先预留足够的内存。在某些情况下,保留向量的最大大小(可能为[256256][50][256])的负/正边是什么?
反面:潜在的内存浪费。积极的一面:更少的CPU时间,更少的堆碎片。这是一个内存/CPU的权衡,最佳选择取决于您的应用程序。如果您没有内存限制(在大多数消费者计算机上有足够的RAM),请考虑提前预留。
要决定保留多少内存,请查看平均内存消耗,而不是峰值(保留25625650256并不是一个好主意,除非经常需要这样的尺寸)