我有一个ILookup<TKey,TElement> lookup
我经常从中获取元素并使用LINQ或foreach
进行迭代。我看起来像IEnumerable<TElement> results = lookup[key];
。
因此,每次使用查找结果时,results
都需要至少枚举一次(如果我先不使用.ToList(),那么如果我多次迭代则更多)。
即使它不是“干净”,使用Dictionary<TKey,List<TElement>>
会不会更好(性能方面),所以只有在构造字典时才会枚举键的所有结果? ToList()的收费是多少?
答案 0 :(得分:15)
ToLookup
LINQ方法一样, ToXXX
使用立即执行。生成的对象没有引用原始源。它实际上 构建了一个Dictionary<TKey, List<TElement>>
- 可能不是那些确切的类型,而是等同于它。
请注意,虽然存在差异,但可能对您有用或者可能没有用 - 如果您为其提供一个不存在的密钥而不是抛出异常,则查找的索引器将返回一个空序列。如果您希望能够通过任何键对其进行索引并迭代相应的值,那么这可以使生活变得更加轻松。
另请注意,虽然没有明确记录,但用于值序列的实现实现ICollection<T>
,因此调用LINQ Count()
方法是O(1) - 它不需要遍历所有元素。
有关详细信息,请参阅我的Edulinq post on ToLookup
。
答案 1 :(得分:4)
假设实现是System.Linq.Lookup
(ILookup
是否有其他实现?),lookup[key]
中显示的元素作为{{1}的字段存储在元素数组中}。反复查找它们不会导致重新迭代源。当然,重建System.Linq.Lookup.Grouping
的成本会更高,但一旦建成,就不再访问源。