Re: Как устроен queue?
От: Кодт Россия  
Дата: 27.03.23 16:03
Оценка: 18 (3) +1
Здравствуйте, TailWind, Вы писали:

TW>Или какой контейнер лучше использовать? (чтобы не было перекопирования элементов)


Внезапно, есть такая штука, как семантика перемещения!
И у вектора она дешёвая.
И у контейнеров, выполняющих переаллокацию (то есть, у того же вектора) — происходит не копирование, а перемещение элементов.
Поэтому можно немножко расслабиться по поводу того, что у тебя элементы — это гигантские vector<UCHAR>. Если всё сделаешь аккуратно, там не будет копирования этих самых гигантских массивов.

deque вообще не перемещает элементы, если не делать вставки-удаления из середины.
По части расхода памяти — list самый избыточный, затем идёт deque (который устроен, как вектор векторов), ну и наконец, собственно vector.

Если очередь короткая, то можно повыбирать между vector, deque и какими-нибудь кольцевыми буферами (их нет в стандартной библиотеке, но можно взять готовый https://www.boost.org/doc/libs/master/doc/html/circular_buffer.html или самому наколхозить, если не лень)
Если очередь длинная, то лучше взять deque, он не будет заниматься сдвигом элементов.
list — во всех случаях проигрывает, потому что он жрёт память. forward_list — чуть дешевле.

А теперь отвечу на вопрос, зачем нужен именно queue.

1) пишешь код, в котором фигурирует std::queue<T>, где T — это твои std::vector<UCAHR>
2) профилируешь его
3) если видишь, что операции push/pop оказались узким местом, то заменяешь std::queue<T> на std::queue<T, another_underlying_container<T>> (экспериментируешь там со списком, кольцевым буфером, рукодельным деком)
4) если видишь, что очередь (больше) не является узким местом, то не паришь себе голову.

Вся выгода тут в том, что, меняя контейнер у адаптера, ты не меняешь весь клиентский код.
Но, конечно, можешь с самого начала написать код работы с очередью, где вместо push/pop будет push_back/pop_front.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.