объект [] против списка против IEnumerable

#c# #list #memory-management

#c# #Список #управление памятью

Вопрос:

У меня есть тонны объектов одного и того же класса obj , которые в настоящее время определены как obj[] .

В большинстве случаев это obj просто default(obj) , не было бы лучше реализовать IEnumerable<obj> вместо этих obj[] списков?

Это должно освободить память для меня, верно? В настоящее время количество этих объектов (под управлением профилировщика памяти) составляет 200 тыс. элементов (постоянно растет).

Помогло бы мне изменение списков на IEnumerables?

Ответ №1:

Фактическая реализация List<T> основана на массивах, поэтому разница в использовании памяти между ними будет незначительной.

Что касается IEnumerable<T> : нет, это не сэкономит вам никакой памяти. элементы null or default вполне приемлемы в IEnumerable<T> , и фреймворк ничего не делает для фильтрации дубликатов. Это невозможно, поскольку объем памяти, связанный со IEnumerable<T> структурой, полностью зависит от класса, который ее реализует, и если вы просто помещаете массив в перечислимую переменную или поле, то вы ничего существенного не меняете. Перечислимые также неизменяемы, поэтому предлагаемый переключатель, вероятно, был бы кардинальным изменением по сравнению с вашей реализацией массива.

Если вас не волнует порядок, вы можете использовать HashSet<T> . На самом деле это выполняет фильтрацию дубликатов, поэтому, если многие или большинство ваших элементов являются таковыми default(T) , то вам потребуется память только для одного из них. Очевидно, что это устранит все дубликаты, а не только те, что по умолчанию, поэтому этот выбор был бы полезен только в том случае, если нет другого дублирования.

Если вам требуется изменяемая семантика — как я подозреваю, вы делаете, если используете массивы, — тогда вы могли быдолжны) переключиться на изменяемый интерфейс, такой как IList<T> , и написать свою собственную реализацию — вероятно, основанную на List<T> — которая игнорирует default(T) при попытке ее добавить. Таким образом, вы могли бы сохранить порядок не- default элементов, никогда не выделяя никакой памяти для хранения default них.

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

Ответ №2:

IEnumerable это просто интерфейс; он не предписывает какой-либо способ хранения данных. List Просто содержит массив, который увеличивается по мере добавления в него новых элементов, но вы можете вызвать TrimExcess() метод для уменьшения массива.

Ответ №3:

Как сказал Марк, IEnumerable — это просто интерфейс. Object[] и List (и большинство других общих коллекций в .NET framework) фактически реализует интерфейс IEnumerable.

Более уместным вопросом было бы, что лучше: Object [] или List или LinkedList и т.д.

Массив объектов (т.Е. Object[]) будет иметь наименьший объем памяти, поскольку размер списка может в два раза превышать объем памяти массива (в зависимости от того, сколько элементов в списке). Когда вы добавляете элемент в список, а внутренний массив заполнен, это удваивает размер массива в попытке ускорить добавление новых элементов в среднем с алгоритмической точки зрения.