LINQ性能问题:总和越少,记录越少

时间:2010-12-10 05:15:25

标签: linq silverlight-4.0 linq-to-entities wcf-ria-services

使用WCF RIA服务的Silverlight 4应用程序

我有一个包含ComboBox和TabControl的页面。每个TabItem都有一个显示RAD Chart控件的usercontrol。 ComboBox包含用于过滤用户控制在图表中显示的数据的项目。当ComboBox选择发生更改时,页面将更新实例/单例类属性上保存的实体集合。将向用户控件通知更改,并且他们访问更新的实体集合以提供给图表控件。一切正常。当ComboBox选择发生更改时,usercontrols将显示基于ComboBox所选项目选择的数据的子集。

让我困惑的是在准备传递给图表控件的值时迭代实体集合所花费的时间。该图表显示了12个月的数据,因此我迭代了12次集合并使用LINQ查询来获取集合中对象属性的Sum。我已将性能问题隔离到执行Sum的单个LINQ查询:

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

这一行代码有时可能需要超过一秒的时间才能运行。这并不可怕,但我正在迭代12个月,所以这行代码运行了12次。

这是踢球者......

顶级ComboBox选项是“所有记录”。所以在我的测试示例中,第一次使用上面的代码行来获得'Sum'时,该集合有500多条记录。它以.2秒的形式返回Sum。我将ComboBox更改为筛选结果的选项,因此集合中只有80条记录。请注意,它不是一组完全不同的记录,它只是满足另一个标准的500的子集。上面的代码行需要1.2秒才能运行。 当我要求500多条记录的总和时,需要0.2秒。当我要求80条记录的总和时,需要1.2秒。

是什么导致这种情况?

谢谢,

1 个答案:

答案 0 :(得分:2)

如何过滤以创建子集? “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 and Deferred Execution