HybridDictionary 类
第一次遇到这个类,查MSDN得到: 在集合较小时,使用 ListDictionary 来实现 IDictionary,然后当集合变大时,切换到 Hashtable。集合大小界定于count=10。
用Reflector查看了一下大致能知道是怎么回事。(习惯了,好奇心驱使,碰到FCL第一反映就是用这个工具look look)
看其Add()方法:
![](/Images/OutliningIndicators/ContractedBlock.gif)
HybridDictionary里拥有两个容器,一个为ListDictionary,一个为Hashtable。当初始化不知其大小时会首先讲数据存放于ListDictionary中,当其规模达到10时,会将ListDictionary里的数据copy到Hashtable中,切换到使用Hashtable。
再看ListDictionary,其结构为node的List,因此是线性的,查找key时也是线性查找。
![](/Images/OutliningIndicators/ContractedBlock.gif)
从HybridDictionary 的存在我们知道在count<10的时候ListDictionary性能效果要比Hashtable好。我们知道Hashtable查找理论上是O(1),而ListDictionary好歹得O(n), 由此可见Hashtable在建散列,获值时还是有一定的额外开销的,毕竟它在调用对象的Equals方法外还需额外做点事情,只不过当集合数据变大后这个开销是不足以计。
HybridDictionary的存在只是为我们提供了一种方便,可用于字典中的元素数量未知的情况,让那些追求极限性能的guys尝点甜头。
貌似最近一位同事遇到的情况就可以排上它。
最近同事在测试性能时发现有个地方挺费时的,里面有个方法是比较两个集合的差异。
原代码是这样实现的
foreach (oject o in firstList)
{
if (secondList.Contains(o))
...
}
foreach (oject o in secondList)
{
...
}
我们知道这种代码效率是很低的,为O(n2)级别,而且还得将两个集合分别做为基去遍历。通过Hashtable改进,完全可以将性能控制在O(n)上。当时讨论建Hashtable也需一点点开销,可能集合数据量很小的时候得不偿失。不过个人觉得这点小性能损失是不足为道的,不过现在看来最佳选择应该是HybridDictionary :)