Чтобы понять разницу, нужно знать, как обычно реализуется deque
.Память выделяется в блоках одинакового размера, и они объединяются в цепочки (как массив или, возможно, вектор).
Итак, чтобы найти n-й элемент, вы найдете соответствующий блок, а затем получите доступ к элементу внутри него.Это постоянное время, потому что это всегда ровно 2 поиска, но это все же больше, чем вектор.
vector
также хорошо работает с API, которые хотят непрерывный буфер, потому что они либо C API, либо являются болееуниверсален в возможности взять указатель и длину.(Таким образом, вы можете иметь вектор внизу или обычный массив и вызывать API из вашего блока памяти.)
Где deque
имеет самые большие преимущества:
- При росте илисжатие коллекции с любого конца
- Когда вы имеете дело с очень большими размерами коллекции.
- При работе с bools вы действительно хотите использовать bools, а не битовый набор.
Второй из них менее известен, но для очень больших размеров коллекции:
- Стоимость перераспределения велика
- Затраты на поиск смежного блока памяти ограничены,так что вы можете быстрее исчерпать память.
Когда я имел дело с большими коллекциями в прошлом и перешел от смежной модели к блочной модели, мы смогли хранить примерно в 5 раз большесбор, прежде чем нам не хватило памяти в 32-битной системе.Отчасти это связано с тем, что при перераспределении фактически необходимо было сохранить старый блок, а также новый, прежде чем скопировать элементы.
Сказав все это, вы можете столкнуться с проблемой std::deque
в системах, которые используют «оптимистическое» распределение памяти.Хотя его попытки запросить большой размер буфера для перераспределения vector
, вероятно, будут отклонены в какой-то момент с bad_alloc
, оптимистическая природа распределителя, вероятно, всегда будет удовлетворять запрос на меньший буфер, запрошенныйdeque
и это может привести к тому, что операционная система завершит процесс, пытаясь получить некоторую память.Какой бы из них он ни выбрал, он может быть не слишком приятным.
Обходные пути в таком случае - либо установка флагов системного уровня для переопределения оптимистического распределения (не всегда выполнимого), либо несколько более ручное управление памятью, например, с помощью собственногораспределитель, который проверяет использование памяти или подобное.Очевидно, не идеал.(Который может ответить на ваш вопрос, так как предпочел бы вектор ...)