Производительность получения уникальных элементов / группы при работе с IEnumerable <T> - PullRequest
0 голосов
/ 27 апреля 2010

Мне было интересно, как я могу улучшить производительность следующего кода:

public class MyObject
{
    public int Year { get; set; }
}

//In my case I have 30000
IEnumerable<MyObject> data = MethodThatReturnsManyMyObjects(); 

var groupedByYear = data.GroupBy(x => x.Year); 

//Here is the where it takes around 5 seconds
foreach (var group in groupedByYear) 
    //do something here.

Идея состоит в том, чтобы получить набор объектов с уникальными значениями года. В моем сценарии только 300 лет включены в список 30000 элементов, поэтому цикл foreach будет выполняться только 6 раз. Таким образом, у нас есть много предметов, которые нужно сгруппировать в несколько групп.

Использование .Distinct () с явным IEqualityComparer было бы альтернативой, но почему-то я чувствую, что это не будет иметь никакого значения.

Я могу понять, что 30000 предметов - это слишком много, и что я должен быть доволен теми 5 секундами, которые я получаю, но мне было интересно, можно ли улучшить сказанное выше с точки зрения производительности.

Спасибо.

EDIT: Ответы, приведенные ниже, заставили меня копнуть немного глубже, только чтобы понять, что 5 секунд, которые я получаю, происходят только при загрузке данных в память из БД. Задержка была замаскирована внутри цикла foreach, поскольку отложенное выполнение IEnumerable задерживало ее до тех пор, пока меня не смутило предположение, что, возможно, GroupBy () может быть реорганизован в нечто более производительное.

Тем не менее, остается вопрос: является ли команда GroupBy () оптимальным способом достижения максимальной производительности в таких случаях?

Ответы [ 2 ]

2 голосов
/ 27 апреля 2010

Это определенно не должно занять много времени.Это работает под отладчиком, или нет?Есть какие-то исключения?Собственность Года выполняет какие-либо вычисления в реальной жизни?Если честно, он должен выполнить это почти мгновенно.

У вас есть короткая, но полная программа, которая демонстрирует, что она занимает много времени?(Если нет, я постараюсь найти его самостоятельно, чтобы получить примерные значения времени.)

Обратите внимание, что если MethodThatReturnsManyMyObjects использует отложенное выполнение для итератора, это может быть причиной - как долгонапример, если вы позвоните data.ToList()?

1 голос
/ 27 апреля 2010

Мне интересно знать: обеспечивает ли ваша MethodThatReturnsManyMyObjects ленивая оценка (т. Е. С использованием ключевого слова yield)? Если это так, , что может быть вашим виновником, а не вызовом GroupBy:

// if MethodThatReturnsManyMyObjects uses yield, then
// it won't be executed until enumeration
IEnumerable<MyObject> data = MethodThatReturnsManyMyObjects();

// still not executed
var groupedByYear = data.GroupBy(x => x.Year); 

// finally executed here
foreach (var group in groupedByYear)
    // ...
...