Вставка вектора C++ & нажимает назад разницу
Я хочу знать, в чем разница(ы) между vector ' s push_back и insert функции.
есть ли структурные различия?
есть ли действительно большая разница в производительности?
3 ответа:
самая большая разница заключается в их функциональности.
push_backвсегда помещает новый элемент в концеvectorиinsertпозволяет выбрать позицию нового элемента. Это влияет на производительность.vectorэлементы перемещаются в памяти только тогда, когда необходимо увеличить его длину, потому что слишком мало памяти было выделено для него. С другой стороныinsertзаставляет переместить все элементы после выбранного положения нового элемента. Вы просто должны сделать место для него. Вот почемуinsertчасто может быть менее эффективным, чемpush_back.
функции имеют различные цели.
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}можно использовать
insertдля выполнения той же работы, что иpush_backСv.insert(v.end(), value).
кроме того, что
push_back(x)тут жеinsert(x, end())(возможно, с немного лучшей производительностью), есть несколько важных вещей, чтобы знать об этих функциях:
push_backсуществует только наBackInsertionSequenceконтейнеры - так, например, он не существует оset. Он не мог, потому чтоpush_back()предоставляет вам, что он всегда будет добавлять в конце.- некоторые контейнеры также могут удовлетворить
FrontInsertionSequenceи ониpush_front. Это удовлетворяетсяdeque, но не наvector.- The
insert(x, ITERATOR)СInsertionSequence, который является общим дляsetиvector. Таким образом, вы можете использовать либоsetилиvectorкак цель для нескольких вставок. Однако,setдополнительноinsert(x), что делает практически то же самое (это первая вставка вsetозначает только ускорить поиск подходящего места, начиная с другого итератора-функция, не используемая в этом случае).обратите внимание на последний случай, что если вы собираетесь добавить элементы в цикл, то делаем
container.push_back(x)иcontainer.insert(x, container.end())будет ли эффективно то же самое. Однако это не будет правдой, если вы получите этоcontainer.end()сначала, а затем использовать его во всем цикле.например,риск следующий код:
copy(a.begin(), a.end(), inserter(v, v.end());это будет эффективно копировать весь
aнаvвектор в обратном порядке, и только если Вам повезет не получить вектор перераспределен для расширение (вы можете предотвратить это, позвонивreserve()во-первых); если вам не так повезло, вы получите так называемый UndefinedBehavior(tm). Теоретически это не допускается, потому что итераторы вектора считаются недействительными каждый раз, когда добавляется новый элемент.если вы сделаете это таким образом:
copy(a.begin(), a.end(), back_inserter(v);он будет копировать
aв концеvв исходном порядке, и это не несет риска недействительности итератора.