将vector追加到vector的最佳方法
std::vector<int> a; std::vector<int> b; std::vector<int> c;
我想通过将b
和c
的元素附加到b
来连接这三个向量。 这是最好的方法,为什么?
1)通过使用vector::insert
:
a.reserve(a.size() + b.size() + c.size()); a.insert(a.end(), b.begin(), b.end()); a.insert(a.end(), c.begin(), c.end()); b.clear(); c.clear();
2)通过使用std::copy
:
a.reserve(a.size() + b.size() + c.size()); std::copy(b.begin(), b.end(), std::inserter(a, a.end())); std::copy(c.begin(), c.end(), std::inserter(a, a.end())); b.clear(); c.clear();
3)通过使用std::move
(从C++11
):
a.reserve(a.size() + b.size() + c.size()); std::move(b.begin(), b.end(), std::inserter(a, a.end())); std::move(c.begin(), c.end(), std::inserter(a, a.end())); b.clear(); c.clear();
在我看来,你的第一个解决scheme是最好的方法。
vector<>::insert
用于添加元素,所以它是最适合的解决scheme。
你可以在目标向量上调用reserve
来保留一些空间,但是除非你添加了很多的vector,否则它可能不会提供很多好处: vector<>::insert
知道将会添加多less个元素,只会避免一个reserve
电话。
注意 :如果这些是更复杂的types(即自定义类,甚至是std::string
)的vector
,那么使用std::move
可以提供一个很好的性能提升,因为它会避免复制构造函数。 但是,对于int
的vector,它不会给你带来任何好处。
注2 :值得一提的是,使用std::move
会导致源vector
的内容不可用。
假设你想复制而不移动,这将是最好的方法:
a.reserve(a.size()+b.size()+c.size()); // Reserve space first a.insert(a.end(),b.begin(),b.end()); a.insert(a.end(),c.begin(),c.end());
如果你想移动:
a.reserve(a.size()+b.size()+c.size()); // Reserve space first a.insert(a.end(),std::make_move_iterator(b.begin()), std::make_move_iterator(b.end())); a.insert(a.end(),std::make_move_iterator(c.begin()), std::make_move_iterator(c.end())); b.swap(std::vector<int>()); // Clear and deallocate space c.swap(std::vector<int>()); // Clear and deallocate space
更新 :您已经多次编辑您的问题,使其成为一个移动的目标。 现在你的第一个select和我的第一个build议非常相似。
第一个是最好的select,因为insert
可以计算它添加的元素数量,并在开始复制之前调整vector大小。 其他人没有这些信息,所以最终可能会在复制之后resize,这会比在开始时resize,或者resize不止一次。
但是,由于@michaelgoldshteyn提示,既然你要做两次插入,你也可以自己resize的最终大小,有可能保存一个resize。
如果你真的想在向量a
追加b
和c
的数据,你必须做插入操作(实际上你是1 ):
a.reserve( a.size() + b.size() + c.size() ); // preallocate memory (see why) a.insert( a.end(), b.begin(), b.end() ); a.insert( a.end(), c.begin(), c.end() );
根据编译器的std::copy
(你的2. )应该一样快。
由于std::vector
在内存中一直是连续的,所以不能移动 (如C ++ 11中定义的那样),并且如果知道最终大小,则必须保留向量 (这将避免不必要的重新分配向量)。 但是,如果您真的担心性能,请将其作为三个std::vector
并在读取它们的数据时迭代它们。