Как сохранить неизвестное количество элементов в С# с большей производительностью? [закрыто]C#

Место общения программистов C#
Ответить
Anonymous
 Как сохранить неизвестное количество элементов в С# с большей производительностью? [закрыто]

Сообщение Anonymous »

Например, у меня неизвестно количество случайных элементов типа A (я получаю его из базы данных, и это может быть большой массив):

Код: Выделить всё

IEnumerable sourceList = GetFromDB();
и мне нужно распределить все эти элементы среди нескольких других отдельных списков элементов, и я делаю это в цикле, используя собственную логику (из-за нее непредсказуемо узнать точное количество элементов в каждом отдельном списке).

Код: Выделить всё

// separateList1  and separateList2 have uppredictable count of elements, so I can't set capacity count for every list in conctructor.
var separateList1 = new List(capacityCount1);
var separateList2 = new List(capacityCount2);
foreach(var item in sourceList)
{
if(CustomLogicTest(item))
separateList1.Add(item);
else
separateList2.Add(item);
}
Поскольку я не могу установить счетчик емкости для каждого списка, я могу использовать только конструктор по умолчанию без счетчика емкости, например:

Код: Выделить всё

var separateList1 = new List();
var separateList2 = new List();
но это нехорошо из-за повторной инициализации внутреннего массива внутри списка каждый раз, когда я добавляю новый элемент и текущий предел массива заполнен.
Поэтому моя идея состоит в том, чтобы использовать СИСТЕМНЫЙ ОБЪЕКТ, который является заглушкой по умолчанию для IEnumerable (я действительно не знаю, как лучше всего называть этот объект) вместо списков.

Код: Выделить всё

var separateList1 = Enumerable.Empty();
var separateList2 = Enumerable.Empty();
foreach(var item in sourceList)
{
if(CustomLogicTest(item))
separateList1 = separateList1.Concat(item.Yield());
else
separateList2 = separateList2.Concat(item.Yield());
}

public static class Ext
{
public static IEnumerable Yield(this T item)
{
yield return item;
}
}
и насколько я понимаю, item.Yield() вернет системную оболочку для последовательности, а отдельныйList1.Concat(item.Yield()); вернет создайте системную оболочку, которая обертывает две другие системные оболочки (пустой массив и item.Yield() ). Таким образом, перемещаясь по циклу, этот код будет рекурсивно создавать оболочки, которые обертывают другие оболочки. И нет необходимости повторно инициализировать внутренний массив, как это сделал бы код, если бы я использовал List.
Итак, мой вопрос: действительно ли этот подход дает преимущества в производительности из-за отсутствия необходимости повторной инициализации внутреннего массива? Или наоборот будет еще хуже из-за множества объектов оберток? На самом деле я не слежу за кодом фреймворка этих объектов-оберток, поэтому не знаю, легкий ли это объект или тяжелый? Как это будет работать с точки зрения производительности, когда я создаю много таких объектов или делаю foreach эту оболочку, которая рекурсивно оборачивает множество других оберток? Сколько памяти потребуется рекурсивным оболочкам?
Так следует ли мне использовать Enumerable с «возвратом доходности» и Concat вместо List с Add?
ОБНОВЛЕНИЕ 1:

Код, который вы опубликовали, не делает ничего, кроме задержки разделения. Результаты все равно придется куда-то девать.

Результаты будут повторяться в foreach.

Сколько элементов и какова логика разделения? Если вы знаете, что у вас всегда будет более 10 предметов, установите соответствующую емкость. Даже если вы понятия не имеете, это уменьшит выделение ресурсов.

Если я использую емкость = 10, а фактическое количество равно 1000000, то это вряд ли уменьшит слишком сильно. .

Обратите внимание, что ваш отдельныйList1.Concat(item.Yield()); код возвращает новое перечисляемое, которое вы не присваиваете переменной, поэтому это бессмысленная операция, поскольку вы никогда не сможете ее повторить.

Я это исправил .
ОБНОВЛЕНИЕ 2:
Я провел тест производительности, и доходность намного хуже, чем у List. https://dotnetfiddle.net/KoT4Qg. А создание последовательности доходности происходит даже медленнее, чем ее создание.
Итак, какое решение? Что делать, если мне нужна последовательность, но я не знаю количества элементов? Всегда использовать новый List() или Всегда использовать новый List(1) ? И неважно, что он будет воссоздавать внутренний массив несколько раз?

Подробнее здесь: https://stackoverflow.com/questions/791 ... perfomance
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»