Проблема производительности LINQ: сумма увеличивается с меньшим количеством записей - PullRequest
0 голосов
/ 10 декабря 2010

Приложение Silverlight 4 с использованием WCF RIA Services

У меня есть страница с ComboBox и TabControl.Каждый TabItem имеет пользовательский элемент управления, который отображает элемент управления RAD Chart.ComboBox содержит элементы, которые используются для фильтрации данных, которые пользовательский элемент управления отображает в диаграммах.При изменении выбора ComboBox на странице обновляется коллекция сущностей, хранящихся в свойстве класса instance / singleton.Пользовательские элементы управления уведомляются об изменении, и они получают доступ к обновленной коллекции объектов для передачи элементу управления диаграммы.Все работаетКогда изменяется выбор ComboBox, пользовательские контроллеры отображают подмножество данных, выбранных на основе выбранного элемента ComboBox.

Меня смущает время, необходимое для перебора коллекции объектов при подготовке значенийпередал на карту управления.На диаграмме отображаются данные за 12 месяцев, поэтому я повторяю коллекцию 12 раз и использую запрос LINQ, чтобы получить сумму для свойства объектов в коллекции.Я выделил проблему производительности для одного запроса LINQ, который выполняет Sum:

Decimal sum = myCollection.Where(m => m.CreationDate.Month == month).Sum(m => (m.SalePrice ?? 0));

Эта одна строка кода иногда может выполняться больше секунды.Это не ужасно, но я перебираю 12 месяцев, так что строка кода запускается 12 раз.

Вот кикер ...

Верхняя опция ComboBox - «все записи».Итак, в моем тестовом примере, когда строка кода выше используется в первый раз для получения «Суммы», коллекция содержит более 500 записей.Возвращает сумму за 0,2 секунды.Я изменяю ComboBox на выборку, которая фильтрует результаты, чтобы в коллекции было только 80 записей.Имейте в виду, это не совсем другой набор записей, это просто подмножество 500, которые соответствуют другим критериям.Строка кода выше занимает 1,2 секунды для запуска. Когда я запрашиваю сумму из 500+ записей, это занимает 0,2 секунды.Когда я запрашиваю сумму из 80 записей, это занимает 1,2 секунды.

Что может вызвать это?

Спасибо,

1 Ответ

2 голосов
/ 10 декабря 2010

Как вы фильтруете, чтобы создать подмножество?Является ли «Collection» запросом Linq, который откладывается до выполнения этой строки?Если это так, то разница в скорости, которую вы видите, может быть применением логики фильтрации.

Одна общая возможность ускорить процесс - вычислить все 12 чисел за один проход.Это достаточно просто с помощью оператора GroupBy Linq:

var AllSums = Collection.GroupBy(m=>m.CreationData.Month).ToDictionary(g => g.Key, g => g.Sum(m => m.SalePrice ?? 0));
var JanuarySum = AllSums[January]; 

Это должно превзойти 12 полностью отдельных циклов.

Редактировать: Вот хорошее описание отложенного выполнения: Linq иОтсроченное выполнение

...