C++ vector的insert和push_back区别

tot*_*ten 72 c++

我想知道vector's push_backinsert函数之间的区别.

是否存在结构差异?

是否存在非常大的性能差异?

Ada*_*der 85

最大的不同是他们的功能.push_back总是在最后添加一个新元素,vectorinsert允许您选择新元素的位置.这会影响性能.vector元素只有在需要增加它的长度时才会在内存中移动,因为为它分配的内存太少.另一方面,insert强制在新元素的选定位置之后移动所有元素.你只需要为它做一个位置.这就是为什么insert效率往往低于push_back.

  • 好吧,几乎同样有效 - 代码需要确定`insert`实际上是在`end()`,所以`insert`中的分支比`push_back`中的分支更多,除非编译器可以计算他们实际上并不需要他们. (18认同)
  • 另一方面,最后插入应该与`push_back`一样有效. (8认同)
  • 我认为额外的比较可以忽略不计. (4认同)
  • @TomerW人们选择C或C++来能够平均每一个机器周期,以提高性能,有时甚至直接在ASM中编写...每一个"if"计数,这不是java .. (4认同)

Jos*_*eld 30

功能有不同的目的.vector::insert允许您将对象插入到指定位置vector,而vector::push_back只是将对象粘贴在末尾.请参阅以下示例:

using namespace std;
vector<int> v = {1, 3, 4};
v.insert(next(begin(v)), 2);
v.push_back(5);
// v now contains {1, 2, 3, 4, 5}
Run Code Online (Sandbox Code Playgroud)

您可以使用insert作为执行相同的任务push_backv.insert(v.end(), value).


Eth*_*ris 8

除了事实之外,它的push_back(x)功能相同insert(x, end())(可能性能稍好一些),关于这些功能有几个重要的事情要知道:

  1. push_back仅存在于BackInsertionSequence容器上 - 例如,它不存在于容器上set.它不能因为push_back()它会让你总是在最后添加它.
  2. 一些容器也可以满足FrontInsertionSequence并且它们具有push_front.这是满足的deque,但不是满足vector.
  3. insert(x, ITERATOR)距离InsertionSequence,这是很常见的setvector.这样,您可以使用setvector作为多个插入的目标.但是,set另外insert(x),它实际上做了同样的事情(这个第一个插入set仅意味着通过从不同的迭代器开始来加速搜索适当的位置 - 在这种情况下不使用的特征).

注意最后一种情况,如果你要在循环中添加元素,那么做container.push_back(x)container.insert(x, container.end())将有效地做同样的事情.但是,如果container.end()先得到它然后在整个循环中使用它,那么这将不是真的.

例如,您可能会以下代码的风险:

auto pe = v.end();
for (auto& s: a)
    v.insert(pe, v);
Run Code Online (Sandbox Code Playgroud)

这将以相反的顺序有效地将整个复制av向量,并且只有当您足够幸运且不能为扩展重新分配向量时(您可以通过reserve()先调用来防止这种情况); 如果你没那么幸运,你会得到所谓的UndefinedBehavior(tm).从理论上讲,这是不允许的,因为每次添加新元素时,vector的迭代器都被视为无效.

如果你这样做:

copy(a.begin(), a.end(), back_inserter(v);
Run Code Online (Sandbox Code Playgroud)

它将在原始顺序a的末尾复制v,这不会带来迭代器失效的风险.