Большой запрос LINQ Grouping, что происходит за кулисами - PullRequest
6 голосов
/ 13 сентября 2011

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

В следующем запросе LINQ используется 'group by' и вычисляется сводная информация.Как вы можете видеть, существует множество вычислений, которые выполняются с данными, но насколько эффективен LINQ за кулисами.

var NinjasGrouped = (from ninja in Ninjas 
    group pos by new { pos.NinjaClan, pos.NinjaRank } 
    into con 
    select new NinjaGroupSummary 
    { 
        NinjaClan = con.Key.NinjaClan, 
        NinjaRank = con.Key.NinjaRank, 
        NumberOfShoes = con.Sum(x => x.Shoes), 
        MaxNinjaAge = con.Max(x => x.NinjaAge), 
        MinNinjaAge = con.Min(x => x.NinjaAge), 
        ComplicatedCalculation = con.Sum(x => x.NinjaGrade) != 0 
        ? con.Sum(x => x.NinjaRedBloodCellCount)/con.Sum(x => x.NinjaDoctorVisits)
        : 0,
    ListOfNinjas = con.ToList() 
    }).ToList(); 
  1. Сколько раз список «ниндзя» повторяется вЧтобы вычислить каждое из значений?
  2. Было бы быстрее использовать цикл foreach для ускорения выполнения такого запроса?
  3. Будет ли добавление «.AsParallel ()» после результата Ninjasв каких-либо улучшениях производительности?
  4. Есть ли лучший способ вычисления итоговой информации для List?

Любой совет приветствуется, поскольку мы используем этот тип кода в нашем программном обеспечении, и я бы очень хотелхотелось бы лучше понять, что делает LINQ под капотом (так сказать).Возможно, есть лучший способ?

1 Ответ

6 голосов
/ 13 сентября 2011

Предполагается, что это запрос LINQ to Objects:

  • Ninjas повторяется только один раз; группы встроены во внутренние конкретные списки, которые вы затем повторяете несколько раз (один раз для агрегации).
  • Использование цикла foreach почти наверняка не ускорит процесс - вы можете получить выгоду от когерентности кэша немного больше (поскольку каждый раз, когда вы выполняете итерацию по группе, вероятно, придется выбирать данные из кэша более высокого уровня или основная память) но я очень сильно сомневаюсь, что это будет значительным. Увеличение боли при его реализации, вероятно, будет значительным, хотя:)
  • Использование AsParallel может ускорить процесс - это выглядит довольно легко распараллеливаемым. Стоит попробовать ...
  • Если честно, для LINQ to Objects не намного лучший способ. Было бы неплохо иметь возможность выполнять агрегирование во время группировки, а Reactive Extensions позволят вам сделать что-то подобное, но на данный момент это, вероятно, самый простой подход.

Возможно, вы захотите взглянуть на сообщение GroupBy в моей серии блогов Edulinq , чтобы узнать больше о возможной реализации.

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