通过IEnumerable <t> </t>上的操作获得唯一元素/组的性能

时间:2010-04-27 14:31:36

标签: c# performance ienumerable

我想知道如何改善以下代码的性能:

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.

我们的想法是获得一组具有唯一年份值的对象。在我的场景中,列表中的30000个项目中只包含6年,因此foreach循环将仅执行6次。所以我们需要将很多项目分组到几个小组中。

将.Distinct()与显式IEqualityComparer一起使用将是另一种选择,但我觉得它不会有任何区别。

我能理解30000项目是否太多而且我应该对我获得的5秒感到满意,但我想知道上述情况是否可以改善性能。

感谢。

编辑: 下面的答案让我深入了解只是意识到当数据从数据库加载到内存中时,我只得到了5秒钟。延迟是在foreach循环中伪装的,因为IEnumerable的延迟执行将其推迟到那一点让我误以为可能会将GroupBy()重构为更高效的东西。

问题仍然存在,GroupBy()命令是在这种情况下实现最佳性能的最佳方式吗?

2 个答案:

答案 0 :(得分:2)

绝对不应该花那么长时间。这是否在调试器下运行?是否抛出任何异常?年份财产是否在现实生活中执行任何计算?说实话,它应该立即执行。

你有一个简短而完整的程序,证明它需要很长时间吗? (如果没有,我会尝试自己想出一个样本时间。)

请注意,如果MethodThatReturnsManyMyObjects对迭代器使用延迟执行,那可能是罪魁祸首 - 例如,如果您调用data.ToList()需要多长时间?

答案 1 :(得分:1)

我很想知道:您的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)
    // ...