Поскольку существует множество ответов, вы можете запутаться, но резюмируем:
Используйте файл std::queue
. Причина этого проста: это структура FIFO. Вам нужен FIFO, вы используете std::queue
.
Это делает ваши намерения понятными для всех и даже для вас самих. А std::list
или std::deque
нет. Список можно вставлять и удалять где угодно, что не является тем, что предполагается в структуре FIFO, и deque
можно добавлять и удалять с любого конца, что также не может сделать структура FIFO.
Вот почему вам следует использовать queue
.
Теперь вы спросили о производительности. Во-первых, всегда помните это важное практическое правило: сначала хороший код, а потом - производительность.
Причина этого проста: люди, которые стремятся к производительности, прежде чем к чистоте и элегантности, почти всегда финишируют последними. Их код превращается в помойную кашу, потому что они отказались от всего хорошего, чтобы по-настоящему ничего не получить.
Если сначала написать хороший, читаемый код, большинство проблем с производительностью решатся сами собой. И если позже вы обнаружите, что ваша производительность недостаточна, теперь легко добавить профилировщик в ваш красивый, чистый код и выяснить, в чем проблема.
Тем не менее, std::queue
это всего лишь адаптер. Он обеспечивает безопасный интерфейс, но использует другой контейнер внутри. Вы можете выбрать этот базовый контейнер, и это дает большую гибкость.
Итак, какой базовый контейнер вы должны использовать? Мы знаем , что std::list
и std::deque
как обеспечить необходимые функции ( push_back()
, pop_front()
и front()
), так как мы решили?
Во-первых, поймите, что выделение (и освобождение) памяти - это не быстрое дело, как правило, потому что для этого нужно обратиться к ОС и попросить ее что-то сделать. A list
должен выделять память каждый раз, когда что-то добавляется, и освобождать ее, когда она исчезает.
A deque
, с другой стороны, выделяет блоки. Он будет выделять реже, чем файл list
. Думайте об этом как о списке, но каждый блок памяти может содержать несколько узлов. (Конечно, я бы посоветовал вам действительно узнать, как это работает .)
Таким образом, только с этим он deque
должен работать лучше, потому что он не так часто работает с памятью. В сочетании с тем фактом, что вы обрабатываете данные постоянного размера, им, вероятно, не придется выделять после первого прохода данных, тогда как список будет постоянно выделять и освобождать.
Второе, что нужно понять, - это производительность кеша . Выход в ОЗУ происходит медленно, поэтому, когда ЦП действительно необходимо, он максимально использует это время, забирая с собой часть памяти в кеш. Поскольку a deque
выделяется фрагментами памяти, вполне вероятно, что доступ к элементу в этом контейнере заставит ЦП также вернуть остальную часть контейнера. Теперь любые дальнейшие обращения к ним deque
будут быстрыми, потому что данные находятся в кеше.
Это не похоже на список, в котором данные размещаются по одному. Это означает, что данные могут быть распределены по всей памяти, и производительность кеша будет плохой.
Поэтому, учитывая это, deque
лучше выбрать a. Вот почему это контейнер по умолчанию при использовании queue
. Тем не менее, это все еще (очень) обоснованное предположение: вам придется профилировать этот код, используя deque
в одном тесте и list
в другом, чтобы действительно знать наверняка.
Но помните: заставьте код работать с чистым интерфейсом, а затем беспокойтесь о производительности.
Джон выражает обеспокоенность тем, что упаковка list
или deque
приведет к снижению производительности. Еще раз, он и я не можем сказать наверняка, не профилируя его сами, но есть вероятность, что компилятор встроит вызовы, которые queue
делает. То есть, когда вы говорите queue.push()
, на самом деле он просто говорит queue.container.push_back()
, полностью пропуская вызов функции.
Еще раз, это только обоснованное предположение, но использование queue
не приведет к снижению производительности по сравнению с использованием базового контейнера raw. Как я уже говорил, используйте queue
, потому что он чистый, простой в использовании и безопасный, и если он действительно станет проблемой, профиль и тест.