为双向量保留空间
Posted
技术标签:
【中文标题】为双向量保留空间【英文标题】:Reserving space for a double vector 【发布时间】:2019-09-16 11:28:39 【问题描述】:假设T
是一个类型,我想创建一个vector<vector<T>>
。我知道最终的大小将是m x n
,其中m
和n
是运行时常量。 (如果它们是编译时常量,我会使用std::array<std::array<T, n>, m>
。)假设在我认真地继续我的程序之前,我有三个选择来处理我的双向量:
选项 1
std::vector<std::vector<T>> dbl_vect(m);
for (auto & v : dbl_vect)
v.reserve(n);
选项 2
std::vector<std::vector<T>> dbl_vect;
dbl_vect.reserve(m);
选项 3
std::vector<std::vector<T>> dbl_vect;
假设我不担心向量重新分配导致迭代器和引用失效,因此我们可以将其从决策过程中移除。
当然,后面的代码会有所不同,因为#1 创建了 dbl_vector 的(空)行,所以我们必须访问这些行而不是推回更多行。
选项#2 似乎没什么用,因为它不知道为每一行保留多少空间。
选项 #1 要求我通过 m
空向量的线性传递并手动调整它们的大小,但它会阻止重新分配。如果T
相当大,我相信这几乎肯定会更好,因为它可以防止复制/移动。
问题:假设T = char
(或选择您最喜欢的 POD 类型)。在什么情况下我应该对选项1和3无动于衷,甚至更喜欢#3?这主要是因为char
的大小相对较小,还是因为编译器将(不)默认初始化char
的方式?如果T
更大,可能是用户定义的,我应该在什么时候开始关心(双向量的大小或T
的大小)?
Here 提出了一个有点类似的问题,关于一个向量和T=int
。
【问题讨论】:
你想通过使用reserve()
而不是仅仅创建你想要的vector
s来解决什么问题?
@SidS 我很清楚,你的意思是一个接一个地创建它们并在我去的时候打电话给push_back
?这可能意味着重新分配,这可能值得避免。
@EricAuld:不,他的意思是从迭代器创建它们,以便它们从一开始就具有值。
@MooingDuck 哦。我假设我的代码比这更复杂,所以我不提前知道它们的值是什么。 (想象一下我正在编写代码以将所有可能的分区返回给我的情况......你明白了)
#4 std::vector<T> vec; vec.reserve(m * n);
【参考方案1】:
如果您知道内部大小为m
,一种可能性是创建std::vector<S>
,其中S
是您的自定义类型,代表std::vector<T>
,但它知道它将有多少条目。建议使用类似的解决方案 here(除了 m
是编译时常量)。
【讨论】:
【参考方案2】:#3 只是默认初始化向量。没有任何收获,因为包含向量的容量为零。动态分配内存很慢,所以为了尽量减少这种情况,我总是选择 #1 或其变体。
【讨论】:
我认为这不是真的。它创建一个空的外部向量并且没有内部向量。 (选项 3 不会告诉它要创建多少个内部向量。)与实际创建 (empty, m) 内部向量的 1 相反,它最终将有 n 个条目。不是说你在大局中错了,但除非我错了,否则你在初始化方面是错的。 是的。包含向量没有元素,我应该更清楚地表达出来 "...依次将值初始化或默认初始化...所有包含的向量。"这就是我所说的选项 3 不会做的事情。不会创建任何包含的向量,只会创建单个包含向量。以上是关于为双向量保留空间的主要内容,如果未能解决你的问题,请参考以下文章