Каковы самые быстрые структуры данных для последовательного вставки / чтения / удаления в C ++?

0

Мне будет дано около 100 тыс. Координат в файле. Но число элементов не фиксировано. И я хочу сохранить их в структуре данных, которая будет самой быстрой для вставки/последовательного чтения/удаления. Хотя структура данных последовательно повторяется в цикле. От 25 до 70% элементов необходимо удалить. Кроме того, порядок координат имеет значение.

В таком случае, какие будут самые быстрые структуры данных для вставки/последовательного чтения/удаления в C++?

Теги:
data-structures
memory-management

3 ответа

6

Ответ во многом зависит от того, как вы действительно собираетесь использовать свой контейнер.

Не паникуйте: используйте typedef для std::vector чтобы начать с (или любого другого conatiner, это не имеет значения) и сделать ваш код общим для контейнера (как это делают алгоритмы STL):

typedef std::vector<Points> Coordinates

После того, как ваша программа будет запущена (и вы знаете, сколько добавить/удалить и т.д.), Выполните ее.

Вы можете бесплатно изменить тип контейнера (возможно, в std::list<> или std::deque), только изменив этот typedef и правильно проверив каждый контейнер в реальных сценариях.

В этот момент вы узнаете, какой контейнер вам нужен.

1

std::list обеспечит самую быструю установку, удаление и чтение SEQUENTIAL. Вы не хотите использовать std::vector так как ему придется перераспределять весь массив при вставках (если вы не укажете предварительно выделенный буфер).

Ознакомьтесь с http://www.cplusplus.com/reference/list/list/. Как вы можете видеть, std :: list является двусвязным списком. Это позволит вам делать вставки/удаление в голове или хвосте списка в постоянное время. Итерация по списку в последовательности также (по существу) происходит так же быстро, как итерация через вектор. Я имею в виду, что обе операции являются постоянными. См. Комментарии ниже о проблемах, связанных с фрагментацией памяти.

0

Там не хватает информации, чтобы действительно предложить лучшее место здесь. Как часто вы вставляете и удаляете? Но некоторая пища для размышлений:

Если ваши координаты trivially copyable std::vector trivially copyable действительно может быть довольно быстрым с memmove. Во время итерации и вы хотите стереть текущий элемент, перемотайте его и уменьшите i или iterator (не имеет значения, если он переполняется для size_t пока вы делаете это последнее, так как он будет правильно переполняться с шагом). То же самое можно сделать с вставкой до тех пор, пока вы позаботитесь о повторном распределении, вы всегда должны reserve если capacity() == size().

Я советовал std::list, мне трудно найти случай для этого. Если вы хотите поведение двойного связанного списка, вы можете сохранить std::tuple< size_t, size_t, Coordinate > а первые два элемента означают смещение к предыдущему и следующему элементу. Это могло бы улучшить поведение кэша, но со временем все равно будет фрагментироваться (в этом случае вы могли бы периодически разложить его, если это возможно). Другой подход заключается, по крайней мере, в использовании пользовательского распределителя для std::list, посмотрите на boost::pool.

  • 0
    Допустим, мы удалим от 50% до 70% элементов.
  • 0
    Прежде всего, если у вас есть координаты 10k, и, скажем, для аргументов, вы будете вставлять еще 10k и стирать 15k этой суммы, фактический обход / стирание / вставка все равно будет составлять, скорее всего, десятые доли секунды на несколько современная машина. Вам нужно, чтобы он шел быстрее или это требует реального времени? В любом случае, я бы попробовал вектор, предложенный вектором, особенно если это не единичный прогон, поскольку производительность вектора со временем не ухудшится.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню