Я работаю над внешним алгоритмом сортировки, который использует std::queue
и должен тщательно сдерживать использование памяти. Я заметил, что во время фазы слияния (которая использует несколько std::queue
фиксированной длины), использование моей памяти увеличивается примерно до 2,5X, что я ожидал. Поскольку std::queue
по умолчанию использует std::deque
в качестве своего основного контейнера, я провел несколько тестов на std::deque
, чтобы определить его служебные данные памяти. Вот результаты, запущенные на VС++ 9, в режиме деблокирования с 64-битным процессом:
При добавлении 100 000 000 char
в std::deque
, использование памяти увеличивается до 252,216K. Обратите внимание, что 100M char
(1 байт) должно занимать 97,656K, поэтому это накладные расходы 154,560K.
Я повторил тест с double
(8 байт) и увидел, что память выросла до 1,976,676K, а 100M double
должна занимать 781 250K для накладных расходов в 1,195,426K!!
Теперь я понимаю, что std::deque
обычно реализуется как связанный список "кусков". Если это так, то почему накладные расходы пропорциональны размеру элемента (из-за того, что размер указателя должен быть зафиксирован на 8 байтов)? И почему это так сильно удалено?
Может ли кто-нибудь пролить свет на то, почему std::deque
использует так сильно замедленную память? Я думаю, что я должен переключить базовые контейнеры std::queue
на std::vector
, так как нет накладных расходов (учитывая, что соответствующий размер reserve
ed). Я думаю, что преимущества std::deque
в значительной степени отрицаются из-за того, что у него такие огромные накладные расходы (что приводит к промахам в кэше, ошибкам страниц и т.д.), И что стоимость копирования элементов std::vector
может быть меньше, учитывая, что общее использование памяти значительно ниже. Это просто плохая реализация std::deque
от Microsoft?