Относительная производительность std :: vector против std :: list и std :: slist?
-
04-07-2019 - |
Вопрос
Для простого связанного списка, в котором произвольный доступ к элементам списка не является обязательным, есть ли существенные преимущества (производительность или иное) в использовании std :: list
вместо std: : вектор код>? Если требуется обратный переход, будет ли эффективнее использовать
std :: slist
и reverse ()
список до перебора его элементов?
Решение
Как обычно, лучший ответ на вопросы о производительности - это профиль Обе реализации для вашего варианта использования и посмотреть, что быстрее. Р>
В общем, если у вас есть вставки в структуру данных (кроме конца), тогда vector
может быть медленнее, иначе в большинстве случаев ожидается выполнение vector
лучше, чем list
, если только для проблем с локальностью данных , это означает, что если два элемента, которые являются смежными в наборе данных, являются смежными в памяти, тогда следующий элемент уже будет находиться в кеше процессора и не должен будет выкидывать страницу памяти в кеш.
Также имейте в виду, что затраты пространства для vector
постоянны (3 указателя), а затраты пространства для list
оплачиваются за каждый элемент, это также уменьшает количество полных элементов (данные плюс накладные расходы), которые могут одновременно находиться в кэше.
Другие советы
Структура данных по умолчанию для C ++ - Вектор .
Рассмотрим следующие моменты ...
1] Обход:
Узлы списков разбросаны по всей памяти, и, следовательно, обход списков приводит к отсутствию кэша . Но обход векторов гладкий.
2] Вставка и удаление:
В среднем 50% элементов должны быть сдвинуты, когда вы делаете это в Vector, но кэши в этом очень хороши! Но со списками вам нужно пройти до точки вставки / удаления ... , так что еще раз ... кэш отсутствует!
И на удивление векторы выигрывают и в этом случае!
3] Хранилище:
Когда вы используете списки, есть 2 указателя на элементы (вперед и назад), поэтому список намного больше, чем вектор!
Для векторов требуется чуть больше памяти, чем для фактических элементов.
У Yout должна быть причина не использовать вектор.
Р> <ч>
Справка:
Я узнал об этом в беседе с лордом Бьярном Страуструпом: https://youtu.be/0iWb_qi2-uI ? Т = 2680 <р> р>
Просто нет. Список имеет преимущества перед Vector, но последовательный доступ не является одним из них - если это все, что вы делаете, то вектор лучше.
Однако ... вектор добавляет дополнительные элементы дороже, чем список, особенно если вы вставляете посередине.
Понять, как реализованы эти коллекции: вектор - это последовательный массив данных, список - это элемент, содержащий данные и указатели на следующие элементы. Как только вы это поймете, вы поймете, почему списки хороши для вставок и плохи для произвольного доступа.
(таким образом, обратная итерация вектора точно такая же, как и для прямой итерации - итератор просто вычитает размер элементов данных каждый раз, список все равно должен переходить к следующему элементу через указатель)
Если вам нужен обратный переход, то слайст вряд ли станет для вас структурой данных.
Обычный (дважды) связанный список дает вам постоянное время вставки и удаления в любом месте списка; вектор дает только амортизированную вставку и удаление с постоянным временем в конце списка. Для вектора вставка и удаление время является линейным в любом месте, кроме конца. Это не вся история; Есть также постоянные факторы. Вектор - это более простая структура данных, которая имеет свои преимущества и недостатки в зависимости от контекста.
Лучший способ понять это - понять, как они реализованы. Связанный список имеет следующий и предыдущий указатели для каждого элемента. Вектор имеет массив элементов, адресуемых по индексу. Из этого вы можете видеть, что оба могут делать эффективный прямой и обратный обход, тогда как только вектор может обеспечить эффективный произвольный доступ. Вы также можете видеть, что накладные расходы памяти связанного списка относятся к элементу, в то время как для вектора он постоянен. И вы также можете увидеть, почему время вставки отличается между двумя структурами.
Некоторые строгие критерии по теме: http://baptiste-wicht.com/posts /2012/12/cpp-benchmark-vector-list-deque.html р>
Как уже отмечалось, непрерывное хранение в памяти означает, что std :: vector лучше для большинства вещей. Практически нет веских оснований для использования std :: list, за исключением небольших объемов данных (где они все могут помещаться в кэш) и / или случаев частого удаления и повторной вставки. Гарантии сложности не относятся к реальной производительности из-за разницы между скоростью кэш-памяти и основной памяти (200x) и тем, как непрерывный доступ к памяти влияет на использование кеша. Смотрите Чендлер Каррут (Google) поговорить о проблеме здесь: https://www.youtube.com/watch?v=fHNmRkzxHWs
И о Майк-Актоне, ориентированном на данные, поговорим здесь: https://www.youtube.com/watch?v=rX0ItVEVjHc
Подробнее о расходах см. в этом вопросе:
Каковы гарантии сложности стандартных контейнеров р>
Если у вас есть слайст, и теперь вы хотите просмотреть его в обратном порядке, почему бы не изменить тип на список везде?