2013-05-07 1 views
32

У меня есть код, в котором я обычно заполняю вектор между 0 и 5000 элементами. Я знаю, что максимум не превышает 5000. Вместо инициализации вектора несколько раз, я хотел бы сделать только один разC++ быстрый способ очистки или стирания вектора

vector<struct> myvector; 
myvector.reserve(5000); 

Однако, чтобы заполнить вектор снова, я должен очистить вектор первый, не изменяя его емкость. Поэтому обычно я вызываю myvector.clear();

Это операция O (n). Есть ли что-то простое, что я могу сделать, чтобы повысить производительность этого или это самое лучшее, что он получит?

+2

Назначает ли существующие элементы разумное решение? –

+0

Нет, потому что у меня может быть 5000 элементов в первый раз и 3500 в следующий раз, и в конце будет 1500 старых элементов ... – user788171

+0

Является ли «разрушение» элементов проблемой? –

ответ

38

Если ваша структура имеет нетривиальный деструктор, тогда ее нужно вызывать для всех элементов вектора, независимо от того, как она опустела. Если ваша структура имеет только тривиальный деструктор, компилятор или стандартная реализация библиотеки могут оптимизировать процесс уничтожения и дать вам операцию O (1).

+0

Есть разница между * «компилятор, вероятно, оптимизирует ...» * и * «реализация может оптимизируйте стоимость ... »* (как сказал в своем ответе @ DavidRodríguez-dribeas). Последний звучит более разумно для меня! – Nawaz

+0

@Nawaz: Я полагаю, это правда. Мое намерение заключалось в том, что «большинство компиляторов выполняют эту оптимизацию, поэтому, возможно, вы используете один из этих компиляторов», но я вижу, как это можно интерпретировать как «иногда компилятор будет, а иногда компилятор не будет оптимизировать это, но обычно это будет ». –

+0

Думаю, вы не поняли мой комментарий. Утверждение * «реализация может оптимизировать стоимость прочь ...» * - это супер-набор, так как он также включает в себя идею * «компилятор, вероятно, оптимизирует» *, в дополнение к возможности «оптимизированного» библиотечного кода. Значит, даже если сам компилятор не выполняет оптимизацию, библиотека может быть записана так, чтобы испускать код «O (1)», когда «value_type» имеет тривиальный деструктор (что и означало @ DavidRodríguez-dribeas, см. его комментарии). – Nawaz

10

Все, что вы делаете, чтобы удалить существующие элементы из вектора, необходимо (потенциально) вызвать деструктор каждого уничтожаемого элемента. Поэтому, с точки зрения контейнера, лучшее, на что вы можете надеяться, - линейная сложность.

Это оставляет только вопрос о том, какие предметы вы храните в векторе. Если вы храните что-то вроде int, что компилятор может/будет знать заранее, у него нет деструктора для вызова, возможно, по крайней мере неплохо, что удаление закончится с постоянной сложностью.

Я сомневаюсь, однако, что изменение синтаксиса (например, clear() против resize() против erase(begin(), end())) приведет к каким-либо существенным различиям вообще. Синтаксис не изменяет тот факт, что (при отсутствии потоковой передачи), вызывающий N деструкторов, является операцией O (N).

23

Стоимость clear() зависит от того, что хранятся в объектах, и в частности, имеет ли они тривиальный деструктор. Если тип не имеет тривиального деструктора, то вызов должен уничтожить все сохраненные объекты, и на самом деле это операция O (n), но вы ничего не можете сделать лучше.

Теперь, если сохраненные элементы имеют тривиальные деструкторы, тогда реализация может оптимизировать стоимость и clear() станет дешевой операцией O (1) (просто сбросив размер - end указатель).

Помните, что для понимания асимптотической сложности вам нужно знать, о чем она говорит. В случае clear() он представляет собой количество вызываемых деструкторов, но если стоимость (скрытая) равна 0, то операция является no-op.

+0

Можете ли вы пояснить, что подразумевается под тривиальным деструктором? Я не знаком с этой терминологией. – user788171

+8

Я думаю, что в этом контексте «тривиальный деструктор» такой же, как «без деструктора». –

+4

@ user788171: Вы можете прочитать [Что такое Агрегаты и POD и как/почему они являются особенными?] (Http://stackoverflow.com/a/7189821/2070725), чтобы понять, что это за весь «тривиальный» материал (прокрутите немного вниз, чтобы достичь «тривиальной» части). – syam