【问题标题】:LINQ performance vs. Dictionary<K,V>LINQ 性能与 Dictionary<K,V>
【发布时间】:2011-10-19 02:31:46
【问题描述】:

在许多情况下,为了简单起见,我宁愿将 List 或 HashSet 与 LINQ 结合使用,而不是使用 Dictionary。但是,我通常坚持使用 Dictionary,因为我认为 Dictionary 会因为它的哈希表实现而具有更高的性能。

例如:

当我在 LINQ 中执行此操作时:

bool exists = hashset.Any(item => item.Key == someKey);

与使用字典的以下等效项相比,我是否会失去显着的性能?

bool exists = dictionary.ContainsKey(someKey); // an O(1) operation

LINQ 查询是否以某种方式进行了优化,使其成为对字典的合理选择?或者上面的 Any() 是一个普通的 O(n) 操作,不管它是在哪种类型的集合上执行的?

【问题讨论】:

  • 你传递给它一个委托在每个项目上执行(直到它在这种情况下返回 true),所以是的,字典查找要快得多(除了一些非常边缘的情况)

标签: c# performance linq data-structures


【解决方案1】:

在您的情况下,您正在消除哈希集的好处,因为在这种情况下Any 是在 IEnumerable 上定义的extension method。它只是像 List 一样迭代哈希集并在每个项目上调用 == 运算符。事实上,这两个代码示例甚至不是严格等价的——LINQ 语句使用 == 运算符,而字典使用 hashcode/equals 相等。这些对值类型和字符串是等价的,但不是对所有类。

你可以这样做:

bool exists = hashset.Contains(item.Key);

这将使用 Hashset 的优化查找,并且不需要像使用 Dictionary 那样保留一个虚拟值。

【讨论】:

  • 但是当我遇到这个问题的时候,我通常希望存储一个Item的集合,而不是一个Item.Key的集合。如果我将 Item 的集合存储在 HashSet 中,除非我使用 LINQ,否则我将无法通过 Key 搜索它们。这很慢。然后我回到字典,这似乎是唯一的出路。
  • 如果 Key 嵌入在值中(例如作为字段或属性),您希望继承 KeyedCollection:msdn.microsoft.com/en-us/library/ms132438.aspx。如果键没有嵌入到值中,那么 Dictionary 就是正确的数据结构。
  • 这就是我想要的。谢谢!很清楚的解释。
  • Equals 和 == 对于值类型是不等价的。您是说“内置值类型”吗?
猜你喜欢
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多