LINQ性能与字典<K,V>

asm*_*smo 3 c# linq performance data-structures

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

例如:

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

bool exists = hashset.Any(item => item.Key == someKey);
Run Code Online (Sandbox Code Playgroud)

与下面的词典相比,我是否会失去显着的表现?

bool exists = dictionary.ContainsKey(someKey); // an O(1) operation
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*ain 9

在你的情况下,你正在消除hashset的好处,因为在这种情况下Any是在IEnumerable上定义的扩展方法.它只是在hashset上迭代,就好像它是一个List并在每个项目上调用==运算符.实际上,这两个代码示例甚至不是严格等效的 - LINQ语句使用==运算符,字典使用hashcode/equals相等.这些对于值类型和字符串是等效的,但不适用于所有类.

你能做的是:

bool exists = hashset.Contains(item.Key);
Run Code Online (Sandbox Code Playgroud)

这将使用Hashset的优化查找,而不需要像使用Dictionary一样保留虚拟值.

  • 如果 Key 嵌入在值中(例如作为字段或属性),您希望对 KeyedCollection 进行子类化:http://msdn.microsoft.com/en-us/library/ms132438.aspx。如果键未嵌入值中,则 Dictionary 是正确的数据结构。 (2认同)