Код: Выделить всё
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;
}
}
Итак, мой вопрос: действительно ли этот подход дает преимущества в производительности из-за отсутствия необходимости повторной инициализации внутреннего массива? Или наоборот будет еще хуже из-за множества объектов оберток? На самом деле я не слежу за кодом фреймворка этих объектов-оберток, поэтому не знаю, легкий ли это объект или тяжелый? Как это будет работать с точки зрения производительности, когда я создаю много таких объектов или делаю 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
Мобильная версия