Цикл Foreach с производительностью оператора Linq - PullRequest
0 голосов
/ 03 мая 2011

Подход Witch лучше, или как лучше это сделать:

    Stuffs[] stuffs = getStuffs();
   1)

    foreach (var stuff in stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue))
    {
    }

   2) 
    foreach (var stuff in stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue).ToList())
    {
    }

   3)
    stuffs = stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue).ToArray();
    foreach (var stuff in stuffs)
    {

    }

Я думаю, что номер 3 лучше для производительности.Есть еще идеи?

Ответы [ 3 ]

2 голосов
/ 03 мая 2011

Как правило: Измерьте!

Для удобства чтения я бы сказал, что гибрид 1 и 3. При такой длинной строке прямо в заголовке foreach код становитсянемного нечитабельно, поэтому я бы поставил запрос в отдельной строке над циклом:

var stuffs = from x in getStuffs()
             where x.StartDate <= DateTime.Now.AddDays(-1) &&
                   x.EndDate != DateTime.MinValue
             select x;

или

var stuffs = getStuffs().Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue);

Как вам угодно.Но после этого используйте простой цикл foreach:

foreach (var s in stuffs) {
}

Также нет необходимости преобразовывать в список, поскольку foreach может выполнять итерацию по любой итерируемой коллекции, включая ленивые вещи LINQ.Преобразование в список, вероятно, на самом деле стоит вашего времени.Если вам нужно, чтобы запрос был оценен за до , то цикл запускается, однако вам может потребоваться сделать это, но это не совсем обычная потребность (по моему опыту).

2 голосов
/ 03 мая 2011

Вы должны проверить, но обычно получение данных и действия, которые вы выполняете в цикле, занимают больше, чем итерации.Первый должен быть быстрее, потому что вы не создаете новый список, который вам здесь не нужен.
Я бы также предложил поместить DateTime.Now.AddDays(-1) в переменную - кроме возможных преимуществ в скорости его значение может измениться во время итерации, что может повлиять на правильность вашей программы.

0 голосов
/ 03 мая 2011

Первый, как правило, лучший по производительности.Он будет фильтровать данные при прохождении через них, поэтому он не выделяет место для списка или массива для хранения всех элементов.

Второй и третий выполняют почти одинаково.Они оба фильтруют данные и помещают результат в массивы, а также увеличивают массив при необходимости путем копирования в новый массив.

Третий метод также заменяет исходные данные массивом отфильтрованных данных, что было бы уместно.если вы используете данные позже.Кроме того, выполнение этого освободит исходные данные, чтобы при необходимости их можно было собирать мусором, что может быть лучше для производительности в особом случае, когда исходный массив действительно огромен, и если в коде используется много памятивнутри цикла.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...