На современных процессорах кеш памяти является королем. Использование кэша эффективно имеет огромное значение, процессор может быть легко остановлен на сотни циклов, когда программа обращается к адресу, содержимое которого не кэшируется, ожидая, что очень медленная шина памяти будет предоставлять данные.
Доступ к памяти наиболее эффективен при последовательном доступе к ней. Вероятность того, что байт будет доступна в кеше, будет тогда наибольшей, она, скорее всего, будет присутствовать в одной строке кэша. Что делает массивы на сегодняшний день наиболее эффективным объектом коллекции, предполагая, что вы последовательно индексируете элементы массива.
Соответственно, все классы коллекции .NET, за исключением LinkedList, используют массивы для хранения данных. В том числе хешированные коллекции (Hashtable, Dictionary, Hashset), они используют массив массивов. Включая ArrayList. LinkedList следует избегать из-за очень плохого местоположения кеша, за исключением того, что основная проблема - дешевая вставка и удаление в случайно известных местах.
Проблема с массивами заключается в том, что их размер исправлен, что затрудняет реализацию коллекций авторазделения, таких как ArrayList. Это решается путем намеренного использования адресного пространства. Всякий раз, когда массив заполняется до емкости, массив перераспределяет и элементы копируются. Перераспределение вдвое превышает предыдущий размер, вы можете наблюдать это из свойства Capacity. В то время как это звучит дорого, алгоритм амортизируется O (1) и подсистема виртуальной памяти в операционной системе гарантирует, что вы фактически не платите за память, которую вы не используете.
Вы можете избежать не очень дешевого копирования, угадывая мощность в передней части. Подробнее об этом в this answer.
Возможно, существует реальный массив, который заменяется более длинным массивом (например, в два раза больше длины оригинала или 1,5 раза), когда для нового элемента больше нет места. – nhahtdh