Универсальный список C# System.Collections.Generic.List<T>
реализован с использованием расширяемого массива в качестве резервного хранилища, аналогично реализации, основанной на большем количестве списков массивов. Ясно, что это дает огромные преимущества при выполнении случайного (индексированного) доступа, например. списки, реализованные как связанные списки.
Однако мне интересно, почему не было принято решение реализовать его как круговой массив. Такая реализация будет иметь такую же производительность O(1) для индексированного произвольного доступа и добавления в конец списка. Но это даст дополнительные преимущества, такие как разрешение операций O(1) перед добавлением (т. е. вставка нового элемента в начало списка) и в среднем вдвое сокращение времени, необходимого для случайных вставок и удалений.
Обзор некоторых ответов на данный момент
Как указал @Hachet, для того, чтобы реализация циклического массива имела производительность индексирования, аналогичную производительности System.Collections.Generic.List<T>
, необходимо, чтобы она всегда росла до емкости, равной степени 2 (так что дешевая операция модуля можно выполнить). Это будет означать, что невозможно точно определить его исходную емкость, указанную пользователем, как это возможно в настоящее время при построении экземпляра списка. Так что это явный компромиссный вопрос.
И, как показали некоторые быстрые и грязные тесты производительности, индексирование может быть примерно в 2-5 раз медленнее для реализации циклического массива.
Поскольку индексирование является очевидным приоритетом, я могу себе представить, что это будет слишком большой штраф по сравнению с лучшей производительностью при операциях добавления и немного лучшей производительностью при случайных вставках/удалениях.
Это дубликат с дополнительной информацией об ответе
Этот вопрос действительно связан с тем, , почему типичные реализации списка массивов не являются двойными. закончился?, который я не обнаружил перед тем, как опубликовать свой вопрос. Я полагаю, что на него не был получен удовлетворительный ответ:
Я не проводил никаких тестов, но мне просто показалось, что будут другие узкие места (например, нелокальные загрузки/хранения), которые значительно превзойдут это. Я, вероятно, приму это, если не услышу чего-то более убедительного, спасибо. — Мехрдад
Ответы на этот вопрос предоставляют дополнительную информацию о том, как можно сделать индексацию циклического списка достаточно эффективной, включая пример кода и некоторые количественные числа, которые делают решения о компромиссе более ясными. Как таковые, они предоставляют информацию, дополняющую ту, которая присутствует в другом вопросе. Поэтому я согласен с тем, что цель этого вопроса была во многом такой же, и я согласен, что его следует считать дубликатом. Однако было бы обидно, если бы новая информация, сопровождающая эту, была бы утеряна.
Также меня все еще интересуют возможные дополнительные причины выбора реализации, которые могут еще не присутствовать в ответах на любой вопрос.
if ((uint)index >= (uint)this.count)
31.08.2013