l我们都知道,当我们想要根据某些键值找到集合中的一个项目时,Dictionary / Hashset等是C#中可用的最快选项。但是,显然他们依赖于设置存储桶并在用作查找参数的任何键值上调用哈希函数 - 这两个都有一些开销。
因此,通过权限,这必须意味着 - 对于一个特定大小的集合 - 循环遍历列表/数组中的每个项目,通过“强力”查找匹配必须更快(即List.Contains方法)< / p>
http://www.dotnetperls.com/dictionary-time上有一篇文章暗示这个阈值是三个项目。坦率地说,我很惊讶一个字典在这么少的项目下表现得更好!
我很好奇你们中是否有人已经完成了自己的基准测试并且可以验证这一点。我也很好奇实例化词典和列表所需的时间 - 上面的文章已经省略了(坦率地说,在大多数插入灯/阅读重的情况下,我们使用字典可能不相关 - 但是在某些情况下,这可能是决定使用哪个的重要因素。
另外:如果是这种情况(并且字典确实是比具有四个或更多值的List更好的选择)那么为什么会这样呢?本文中基准测试的示例使用字符串键 - 默认字符串相等运算符/ IEquatable实现的性能成本是否比我意识到的要大得多?字典是否总是在查找期间调用密钥的IEquatable实现 - 或者仅在哈希冲突的情况下调用?
最后:如果密钥的类型是更简单的相等测试(如Int32 / Int64 / Guid),那么这三个项目的阈值是否会大不相同?
答案 0 :(得分:2)
提供ListDictionary
课程就是您提到的原因,并且它已经描述为here,建议如下:
建议用于通常包含少于10个的集合 项目
Microsoft还提供HybridDictionary
描述的here,以便您充分利用这两个方面。它描述了它的典型用法如下:
对于a中元素数量的情况,建议使用此类 字典未知。它利用了改进的性能 具有小集合的ListDictionary,并提供灵活性 切换到更好地处理更大集合的Hashtable 比ListDictionary。
至于您的具体情况,唯一可以看出效果最好的方法是基准。
(请注意,上面的示例仅供参考!使用新的.NET通用集合通常会好得多......)
答案 1 :(得分:1)
您的文章可能没有详细说明设置词典/列表的成本的原因是它很大程度上是微不足道的。就此而言,如果您要在数据结构中进行单一查找,那么实现它的方式并不重要,因为这将花费很少的时间。
我们关心的是访问,因为通常我们会多次访问数据结构,这些重复访问的效果将大大超过设置时间的任何增益。
关于为什么即使项目很少,列表也会变慢:这是因为这不是列表的设计目的。这里的关键是计算通常比内存访问快得多。如果您正在寻找数据结构中的特定内容,那么使用一种算法可以告诉您在哪里查看(哈希函数)并且内存访问量最小,这样可以让您显着提高速度。如果您需要按顺序访问项目(通常是字符串的情况),那么列表就是您想要的。