Я работаю над внешним алгоритмом сортировки, который использует 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?