枚举ILookup结果的成本?最好总是使用Dictionary <tkey,list <telement>&gt;?</tkey,list <telement>

时间:2012-09-12 13:19:18

标签: c# .net

我有一个ILookup<TKey,TElement> lookup我经常从中获取元素并使用LINQ或foreach进行迭代。我看起来像IEnumerable<TElement> results = lookup[key];

因此,每次使用查找结果时,results都需要至少枚举一次(如果我先不使用.ToList(),那么如果我多次迭代则更多)。

即使它不是“干净”,使用Dictionary<TKey,List<TElement>>会不会更好(性能方面),所以只有在构造字典时才会枚举键的所有结果? ToList()的收费是多少?

2 个答案:

答案 0 :(得分:15)

与所有其他ToLookup LINQ方法一样,

ToXXX使用立即执行。生成的对象没有引用原始源。它实际上 构建了一个Dictionary<TKey, List<TElement>> - 可能不是那些确切的类型,而是等同于它。

请注意,虽然存在差异,但可能对您有用或者可能没有用 - 如果您为其提供一个不存在的密钥而不是抛出异常,则查找的索引器将返回一个空序列。如果您希望能够通过任何键对其进行索引并迭代相应的值,那么这可以使生活变得更加轻松。

另请注意,虽然没有明确记录,但用于值序列的实现实现ICollection<T>,因此调用LINQ Count()方法是O(1) - 它不需要遍历所有元素。

有关详细信息,请参阅我的Edulinq post on ToLookup

答案 1 :(得分:4)

假设实现是System.Linq.LookupILookup是否有其他实现?),lookup[key]中显示的元素作为{{1}的字段存储在元素数组中}。反复查找它们不会导致重新迭代源。当然,重建System.Linq.Lookup.Grouping的成本会更高,但一旦建成,就不再访问源。