STL вектор против списка: наиболее эффективно для списков смежности графов? - PullRequest
6 голосов
/ 26 марта 2011

Списки занимают большую часть своего времени при выделении памяти при нажатии push_back.С другой стороны, векторы должны копировать свои элементы, когда необходимо изменить размер.Следовательно, какой контейнер наиболее эффективен для хранения списка смежности?

Ответы [ 4 ]

13 голосов
/ 26 марта 2011

Я не думаю, что на это можно ответить с абсолютной уверенностью.Тем не менее, я предполагаю, что есть хотя бы 90% -ная вероятность того, что вектор будет лучше.Список смежности фактически предпочитает вектор больше, чем многие приложения, потому что порядок элементов в списке смежности (обычно) не имеет значения.Это означает, что когда вы добавляете элементы, это обычно в конец контейнера, а когда вы удаляете элемент, вы можете сначала поменять его на конец контейнера, так что вы добавляете или удаляете только в конце.

Да, вектор должен копировать элементы при расширении, но на самом деле это почти никогда не вызывает существенных проблем.В частности, экспоненциальный коэффициент расширения вектора означает, что среднее число копий элементов стремится к константе - и в типичной реализации эта константа составляет примерно 3.

Если вы находитесь вВ ситуации, когда честное копирование представляет собой реальную проблему (например, копирование элементов очень дорого), мой следующий выбор после вектора все равно не будет в списке.Вместо этого я, вероятно, рассмотрю возможность использования std :: deque.Это в основном вектор указателей на блоки объектов.Ему редко приходится копировать что-либо, чтобы выполнить расширение, и в редких случаях, когда это происходит, все, что он должен копировать, это указатели, а не объекты.Если вам не нужны другие уникальные возможности deque (вставка / удаление в постоянное время на любом конце), вектор обычно является лучшим выбором, но даже в этом случае deque почти всегда является лучшим выбором, чем список (т.е. вектор обычнопервый выбор, deque довольно близкая секунда, и список довольно отдаленного последнего).

1 голос
/ 26 марта 2011

Ответ зависит от варианта использования.PS @quasiverse - векторы вызывают realloc, когда память, которую вы «:: резервируете», явно или неявно, исчерпывает

Если у вас есть постоянно меняющийся список смежности (вставляет и удаляет), список будет лучшим.Если у вас более или менее статический список смежности, и большую часть времени вы выполняете обходы / поиски, то вектор даст вам наилучшую производительность.

0 голосов
/ 26 марта 2011

Вы можете добавить к этому сравнению третий вариант: список со специализированным распределителем.

Использование распределителей для небольших объектов фиксированного размера может значительно увеличить скорость выделения / освобождения ...

0 голосов
/ 26 марта 2011

Контейнеры STL не определены жестко, поэтому реализации могут отличаться.Если вы осторожны, вы можете написать свой код, чтобы ему было безразлично, используется ли вектор или список, и вы можете просто попробовать их, чтобы увидеть, что быстрее.Учитывая сложность эффектов кэша и т. Д., Практически невозможно предсказать относительную скорость с какой-либо точностью.

...