【发布时间】:2014-04-05 08:40:16
【问题描述】:
l我们都知道,当我们想根据某个键值在集合中查找一项时,Dictionary/Hashset 等是 C# 中可用的最快选项。但是,显然它们依赖于设置存储桶并在用作查找参数的任何键值上调用哈希函数 - 这两者都有一些开销。
因此,按权利,这必须意味着 - 对于达到一定大小的集合 - 循环遍历列表/数组中的每个项目以“蛮力”寻找匹配项必须更快(即 List.Contains 方法)
http://www.dotnetperls.com/dictionary-time 上有一篇文章表明此阈值是 三个 项。坦率地说,我很惊讶字典用这么少的项目表现得更好!
我很好奇你们中是否有人做过自己的基准测试并可以验证这一点。我也对实例化 Dictionary 和 List 所需的时间感到好奇——上面的文章忽略了这一点(坦率地说,在大多数插入轻/阅读量大的情况下,我们会使用字典,因为它可能无关紧要——但是在某些情况下,这可能是决定使用哪个的重要因素。
另外:如果是这种情况(字典确实是比具有四个或更多值的列表更好的选择)那么为什么会这样呢?本文中的基准示例使用字符串键 - 默认字符串相等运算符/IEquatable 实现的性能成本是否比我意识到的要大得多? Dictionary 是否总是在查找期间调用键的 IEquatable 实现 - 还是仅在哈希冲突的情况下调用?
最后:如果键的类型是更简单的相等测试(如 Int32/Int64/Guid),这三个项目的阈值是否会有很大不同?
【问题讨论】:
-
你做过基准测试吗?是的,字典总是必须调用 Equal 来确认,因为多个字符串可以(将)散列到相同的值。字典可以仅根据哈希来拒绝许多不匹配,这可能是它很快胜出的原因,但这也取决于访问模式。例如。如果最受追捧的项目位于列表的开头,则列表搜索可能会获胜。
-
嗨“500” - 不,我自己没有做过任何基准测试。虽然这看起来有点背对前,但我想我可能会问这里是否有人在潜入自己之前做了一些非常彻底的基准测试(并在野外进行了讨论)。如果没有人打扰,而你们中的一些人认为这值得,那么我会做一些测试。
标签: c# list dictionary benchmarking hashset