Возможный дубликат:
Почему я предпочитаю использовать vector для деку
Мне любопытно, почему std::vector
гораздо популярнее, чем std::deque
. Deque почти так же эффективен при поиске, более эффективен при вставке (без vector :: reserve) и позволяет вставлять / удалять спереди.
Херб Саттер однажды рекомендовал если вы хотите использовать вектор, просто предпочитайте deque (Я перефразирую). Однако в недавнем разговоре о Написание современного C ++ он снова настоятельно рекомендует подумать о std::vector
как контейнер по умолчанию. Согласно GOTW Я связал ранее, даже стандарт имеет аналогичную формулировку.
Есть ли причина для такого несоответствия? Это просто так vector
проще и общеизвестно, или есть техническая причина? Или это vector
это просто кулер имя ..?
Я не могу говорить за кого-то еще, но я могу за себя.
Когда я впервые прочитал о std::deque
Я подумал, что это достаточно круто, что какое-то время я рассматривал его не только как контейнер по умолчанию, но и как почти только контейнер, который я использовал.
Затем кто-то спросил о том, почему, и я подробно объяснил его достоинства и почему он был лучшим контейнером для использования практически во всем, и как он был гораздо более универсальным, чем std::vector
,
К счастью, парень, ставящий под сомнение мое решение по этому поводу, был достаточно убедителен, и я провел некоторое тестирование. Тестирование показало, что почти в каждом случае std::deque
был медленнее, чем std::vector
— часто существенным фактором (например, около 2). На самом деле, из кода, который я написал, используя std::deque
заменяю std::deque
с std::vector
ускорился во всех случаях, кроме нескольких.
я использовал std::deque
с тех пор в некоторых случаях, но определенно больше не рассматривают его как значение по умолчанию. Простой факт заключается в том, что в обычной реализации это заметно медленнее, чем std::vector
за самый цели.
Я должен добавить, однако, что я достаточно уверен, что при правильном мог быть почти эквивалентным std::vector
практически во всех случаях. Большинство используют представление, которое, несомненно, великолепно с асимптотической точки зрения, но в реальном мире не работает так чудесно (для многих целей).
std::vector
очень хорошо понят, прост и совместим с C (как с точки зрения разметки памяти, так и с точки зрения использования указателей в качестве итераторов).
Для некоторых операций это также более эффективно, чем std::deque
, Доступ к элементам по индексу является одним из примеров.
Для данной задачи имеет смысл использовать простейший контейнер, который хорошо справляется со своей задачей. Во многих случаях этот самый простой контейнер std::vector
,
Люди используют std :: vector вместо std :: deque по простой причине. Они взаимодействуют со многими библиотеками C и имеют функции с параметрами, для которых требуется указатель на непрерывное хранилище, что std :: deque не гарантирует (не может).
Другая причина заключается в том, что когда вы создаете код в соответствии с std :: deque, и ваши требования изменяются, так что вам приходится поддерживать непрерывный доступ, вам придется немного рефакторинга.
Я вынужден упомянуть, что есть библиотеки там, авторы которых утверждают, что создали более эффективные векторные реализации, чтобы преодолеть неэффективность, когда вместимость увеличена.
Структура std::deque
немного сложнее, что делает наивную итерацию немного дороже, чем std::vector
, Вставки в std::vector
с его перераспределением, как правило, не является большой проблемой, особенно при использовании reserve()
и только добавление до конца. Кроме того, есть более простые для понимания правила признания std::vector
хотя на самом деле это преимущество std::deque
что объекты остаются на месте при вставке / удалении только на обоих концах (обратите внимание, что std::deque
итераторы становятся недействительными при каждой вставке, независимо от того, где вставка происходит). Еще один плюс для std:vector
является гарантией того, что значения являются непрерывными в памяти, что приводит к меньшему выделению памяти.
Я думаю, я бы порекомендовал использовать std::deque
алгоритмы были последовательно оптимизированы для использования сегментированных последовательностей (я не знаю, что любая стандартная библиотека C ++ делает эту оптимизацию), и пользователи обращались к последовательностям последовательно, используя алгоритмы (насколько я могу судить, только небольшая часть пользователей считает вариант использовать алгоритмы). Иначе я бы заподозрил, что std::deque
это лучший вариант в отношении производительности, только если вы используете его специфические свойства (например, что объекты остаются на месте и что вы можете вставить / удалить в конце). Однако стоит описать две альтернативы.
Помимо std::vector
Будучи наиболее известным контейнерным классом, он также имеет ряд преимуществ перед std::deque
а именно:
std::deque
требует дополнительного косвенного доступа для доступа к элементам в отличие от случая std::vector
, std::deque
должны быть умные указатели, а не указатели, как в случае std::vector
,std::vector
гарантированно будут смежными и, следовательно, совместимы с функциями в стиле c, которые принимают массивы в качестве параметров.std::deque
не оказывают никакой поддержки, чтобы контролировать емкость и момент перераспределения.Особенно последний пункт заслуживает внимания.