【发布时间】:2011-10-04 17:02:49
【问题描述】:
我正在使用 Dictionary
我记得一些散列算法无法按顺序添加键。
.Net 是这种情况吗?
如果是这样,我有什么选择? (任何整洁的库?)
数据一旦添加就相当静态。通过随机化器添加数据是否值得?
PS 我已经签出:
【问题讨论】:
标签: .net algorithm hash dictionary
我正在使用 Dictionary
我记得一些散列算法无法按顺序添加键。
.Net 是这种情况吗?
如果是这样,我有什么选择? (任何整洁的库?)
数据一旦添加就相当静态。通过随机化器添加数据是否值得?
PS 我已经签出:
【问题讨论】:
标签: .net algorithm hash dictionary
查询的性能应该独立于将键添加到哈希表中的顺序。即使存在冲突,插入元素也很容易通过链接进行 O(1) 分摊。
您是否实际测量过性能问题?如果没有,请不要费心进行更改。如果是这样,请考虑编写一个针对顺序索引进行优化的类。
【讨论】:
注意:我所说的“序列”是指递增一的数字序列。
实际上,如果添加到字典中的唯一键是按顺序排列的(没有重复或间隙),那是最好的情况。在 .Net 的当前实现中(可能随时更改,因此您不应依赖其中任何一个),所有数字序列的 long.GetGashCode() 返回一个数字序列。并且桶数是计算字典的模容量。这意味着在这种情况下,您可以保证不会发生冲突。
如果您有多个长度相同的序列,最坏的情况是它们都发生冲突,并且每个使用的存储桶将包含每个序列的一个项目。不过,这不太可能。在一般情况下,您会遇到一些冲突,但平均检索时间很可能仍为 O(1)。
(上面有一个小小的谎言。对于每一次跨越 32 位边界,一个序列的哈希码序列将有一个数字的间隙,因为 long.GetHashCode() 的实现方式。 )
【讨论】:
int.GetHashCode() 直接返回那个int。
对于这么多项目,字典可能会产生大量开销,并且它依赖于良好的哈希分布以获得理想的性能。
您可能想针对其他方法运行一些基准测试,是否可以简单地分配一个数组并使用键作为索引?比如 object[long],如果你只有 0 到 100 万个可能的值,那么数组占用的空间不到 8MB,而且比 Dictionary 快得多。
如果您不能直接这样做,您可以查找唯一的 long 到 int 索引吗?例如,有一个字典可以让您将 long 转换为一个不断增加的 int,当一个新的 long 出现时,您在它被分配到数组中的位置之前还没有看到。
或者可能使用更复杂的方法来处理锯齿状数组,例如 object[sequenceInt][uniqueIndexInt]。这真的取决于您以后将如何访问数据
【讨论】: