2014-02-17 2 views
0

В следующем коде, который более эффективен, вызывает изменение размера или стирание?, который быстрее использует стирание или изменение размера в векторе?

vector<int> a(5000); 
//.... 
vector<int>::iterator it = remove(a.begin(),a.end(),8) 

a.resize(std::distance(a.begin(),it)); 
//or 
a.erase(it,a.end()); 

Я думаю, что это зависит от количества дублирующих элементов?

+1

Оба являются субоптимальными, так как для сохранения данных смежно требуется 'vector': знак того, что вы не используете соответствующий контейнер. – Bathsheba

+4

@Bathsheba Кажется, это подходящий контейнер для меня. Как правило, очень мало случаев, когда вы должны использовать что-либо другое, кроме 'std :: vector' (для неассоциативного контейнера). –

+0

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

ответ

1

«Я думаю, это зависит от количества повторяющихся элементов?»

Nope. Нет деструктора для int, поэтому 1 дубликат или 1000 не имеет значения. Все, что нужно сделать, это установить внутреннюю запись нового конца используемых элементов. Следовательно, производительность remove() - это дорогостоящая вещь, а не resize/erase. (И даже если бы существовал деструктор, они зацикливались на том же количестве вызывающих его элементов, принимая почти ровно одно и то же время).

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

  • , что они делают это и не обновлять некоторые члены «размер» не предусмотрено в стандарте, но каждая реализация я действительно смотрел в магазинах «конец» указатель, который имеет смысл, поскольку он поддерживает iter != v.end() где итераторы реализованы в виде указателей без более медленных начальных арифметических вычислений размера для end(), а также столь же уродливого специального корпуса, поэтому приращение итератора конца-1 создает некоторое состояние дозорного.
3

Число дубликатов, равное, у них будет эквивалентная сложность. Когда сокращается вектор, resize определяется в терминах erase:

n3337, 23.3.6.3 говорит:

void resize(size_type sz);

9 Эффекты: Если sz <= size(), что эквивалентно erase(begin() + sz, end());. [...]

1

Что говорит профайлер? Это может меняться от одной реализации к другому (хотя только постоянным фактор — сложность должна быть одинаковой).

В этом отношении: профайлер показал, что вы слишком много теряете ? Идиоматический способ написания этого:

a.erase(std::remove(a.begin(), a.end(), 8), a.end()); 

Если профайлер явно не говорит, что это узкое место, вы должны записать его в идиоматическом способе, так что C++ программисты признают сразу, что происходит, и Дон» t тратить время , признавая, что вы делаете то же самое, и задаетесь вопросом, почему вы не делали этого по идиоматическому пути.

Смежные вопросы