Списки имеют ужасную (несуществующую) локальность кэша. Каждый узел имеет новое распределение памяти и может быть где угодно . Таким образом, каждый каждый раз, когда вы следуете указателем от одного узла к другому, вы переходите на новое, не связанное с этим место в памяти. И да, это немного ухудшает производительность. Промах в кеше может быть на два порядка медленнее, чем в кеше. В векторе или в deque, почти каждый доступ будет попаданием в кеш. Вектор - это один непрерывный блок памяти, поэтому итерации по нему выполняются настолько быстро, насколько это возможно. Deque - это несколько меньших блоков памяти, поэтому он вызывает случайную потерю кеша, но они все еще будут редкими, и итерация будет очень быстрой, поскольку вы получаете в основном попадания в кеш.
В списке будут почти все ошибки кеша. И производительность будет отстой.
На практике связанный список вряд ли является правильным выбором с точки зрения производительности.
Редактировать :
Как отмечается в комментарии, еще одна проблема со списками - это зависимости данных. Современный процессор любит перекрывать операции. Но он не может этого сделать, если следующая инструкция зависит от результата этой инструкции.
Если вы перебираете вектор, это не проблема. Вы можете вычислить следующий адрес для чтения на лету, даже не проверяя память. Если вы сейчас читаете по адресу x
, то следующий элемент будет расположен по адресу x + sizeof(T)
, где T - тип элемента. Таким образом, там нет никаких зависимостей, и ЦП может начать загрузку следующего элемента или следующего за ним сразу же, продолжая обрабатывать более ранний элемент. Таким образом, данные будут готовы для нас, когда они нам понадобятся, и это также поможет скрыть стоимость доступа к данным в ОЗУ.
В списке нам нужно следовать указателю с узла i
на узел i+1
, и пока i+1
не будет загружен, мы даже не знаем, где искать i+2
. У нас есть зависимость от данных, поэтому процессор вынужден читать узлы по одному, и он не может начать читать будущие узлы раньше времени, потому что он еще не знает, где они находятся.
Если бы в списке не было всех промахов кэша, это не было бы большой проблемой, но, поскольку мы получаем много промахов кэша, эти задержки являются дорогостоящими.