Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字典查找性能优于列表的点?_C#_List_Dictionary_Benchmarking_Hashset - Fatal编程技术网

C# 字典查找性能优于列表的点?

C# 字典查找性能优于列表的点?,c#,list,dictionary,benchmarking,hashset,C#,List,Dictionary,Benchmarking,Hashset,我们都知道,当我们想根据某个键值在集合中查找一项时,字典/哈希集等是C#中可用的最快选项。但是,很明显,它们依赖于设置bucket和对用作查找参数的任何键值调用哈希函数,这两者都有一定的开销 所以说权限,这必须意味着,对于某个大小的集合,通过“暴力”在列表/数组中的每个项上循环查找匹配项的速度必须更快(即list.Contains方法) 有一篇文章指出这个临界点是三个项目。坦率地说,我很惊讶一本字典能用这么少的条目做得更好 我很好奇,你们中是否有人已经做了自己的基准测试,并且能够验证这一点。我还

我们都知道,当我们想根据某个键值在集合中查找一项时,字典/哈希集等是C#中可用的最快选项。但是,很明显,它们依赖于设置bucket和对用作查找参数的任何键值调用哈希函数,这两者都有一定的开销

所以说权限,这必须意味着,对于某个大小的集合,通过“暴力”在列表/数组中的每个项上循环查找匹配项的速度必须更快(即list.Contains方法)

有一篇文章指出这个临界点是三个项目。坦率地说,我很惊讶一本字典能用这么少的条目做得更好

我很好奇,你们中是否有人已经做了自己的基准测试,并且能够验证这一点。我还对实例化字典和列表所需的时间感到好奇——上面的文章遗漏了这一点(坦率地说,在大多数插入量小/阅读量大的情况下,我们会使用字典,因为它可能不相关——但在某些情况下,这可能是决定使用哪一个的一个重要因素)

另外:如果是这样的话(而且字典确实比包含四个或更多值的列表更好),那么为什么会这样呢?本文中基准测试的示例使用字符串键-默认字符串相等运算符/I可满足实现的性能成本是否比我意识到的要大得多?字典在查找过程中是否总是调用键的IEquatable实现,或者仅在哈希冲突的情况下调用


最后:如果键的类型是具有更简单的相等性测试(如Int32/Int64/Guid)的,那么三个项的阈值会有很大不同吗?

提供
ListDictionary
类的原因正是您提到的,并且对其进行了描述,建议如下:

推荐用于通常少于10个的集合 项目

微软还提供了一个HybridDictionary,让您能够充分利用这两个世界。其典型用途描述如下:

建议将此类应用于以下情况,即 字典是未知的。它利用了改进的性能 具有小集合的ListDictionary,并提供了灵活性 切换到能够更好地处理较大集合的哈希表 而不是字典

至于您的具体情况,查看哪种性能最好的唯一方法是基准测试


(请注意,上面的示例仅供参考!使用新的.NET通用集合通常会更好…

您的文章可能没有详细介绍设置字典/列表的成本,原因是它基本上是琐碎的。就这点而言,如果要在数据结构中执行一次查找,那么如何实现其实并不重要,因为它只需要很短的时间

我们关心的是访问,因为通常我们要多次访问一个数据结构,这些重复访问的影响将大大超过在设置时间内获得的任何收益


关于为什么一个列表即使只有很少的项目也会慢一些:这是因为列表不是为这个目的而设计的。这里的关键是计算通常比内存访问快得多。如果您要在数据结构中查找特定的内容,那么使用一种算法,通过最小的内存访问告诉您在哪里查找(哈希函数),可以显著加快速度。如果您需要按顺序访问项目(通常是字符串),那么您需要的就是列表。

您做过基准点标记吗?是的,字典总是需要调用Equal来确认,因为多个字符串可以(将)散列为相同的值。字典可以仅基于散列拒绝许多不匹配,这可能是它很快胜出的原因,但这也取决于访问模式。例如,如果最受欢迎的项目位于列表的开头,则列表搜索可能会获胜。您好“500”-不,我自己没有做过任何基准测试。虽然这可能看起来有点背道而驰,但我想我可能会问这里的人在投入自己的研究之前是否已经做了一些非常彻底的基准测试(并在野外进行了讨论)。如果没有人打扰,你们中的一些人认为这是值得的,那么我会做一些测试。可能是Hi Baldrick的复制品(很好的昵称btw):由于ListDictionary和HybridDictionary都是在泛型出现前1.1天从.Net中获得的,因此使用引用类型键/值时装箱的成本肯定会抵消它们可能提供的性能改进的一大部分吗?这当然是一个好问题本身。。。你们中有人在这个(后.net 2.0)时代使用过这些收藏吗?@Daniel Scott:谢谢!我并不是建议你使用它们——我只是从微软那里提供证据,证明字典方法往往优于列表(即大约10个),以及他们获得更一般解决方案的方法(构建一个HybridDictionary类)。值得一提的是,旧的集合只包含值类型的box/unbox-对于引用类型,您只是在强制转换。呃-我今天一定有点昏昏欲睡-我想说的是“使用值类型时”(而不是使用引用类型时)。但是,是的,你是对的-一个字符串键/一些引用类型值的ListDictionary应该运行得很好。我想这是我们很多人都遵循的一种教条,就是如此普遍地避免使用这些旧的非通用集合。@DanielScott:一般来说,避免使用旧集合是一个好计划!:)我在我的回答中添加了一个注释。嗨,丹尼尔,谢谢你的回复。这是一个有趣的观点(计算速度比数据访问速度快)。我认为访问列表中的每个项目(通过索引)所需的时间(这是一个非常小的换行)