鉴于.Net能够通过IntPtr检测位数(通过反射器查看大量的标记是不安全的,但是 - 很遗憾)我一直认为GetHashCode返回一个int可能是短视的。
我知道最终有一个好的哈希算法,Int32提供的数十亿个排列绝对足够,但即便如此,可能的哈希值集合越窄,散列的密钥查找越慢,因为需要更多的线性搜索。
同样 - 我是唯一一个发现这个有趣的人:
struct Int64{
public override int GetHashCode()
{
return (((int) this) ^ ((int) (this >> 0x20)));
}
}
虽然Int32只返回this
。
如果由于性能问题而无法解决IntPtr问题,那么实现IEquatable等的IHashCode可能会更好吗?
随着我们的平台在内存容量,磁盘大小等方面变得越来越大,32位哈希的日子肯定已经足够了?
或者仅仅是通过接口抽象散列或根据平台调整散列大小所涉及的开销超过任何潜在性能优势的情况?
答案 0 :(得分:12)
Int64散列函数用于确保考虑所有位 - 因此基本上它将前32位与底部32位进行异或运算。我无法想象一个更好的通用目的。 (截断到Int32将不合适 - 你怎么能正确地散列在低32位中全部为零的64位值?)
如果使用IntPtr作为散列返回值,那么代码必须具有条件分支(是32位?是64位吗?等),这会减慢散列函数,从而打败整个点。
我想说如果你的哈希表实际上有20亿个桶,你可能还是在编写一个完整的自定义系统的阶段。 (可能数据库是一个更好的选择?)在这个尺寸下,确保均匀填充铲斗将是一个更紧迫的问题。 (换句话说,一个更好的哈希函数可能会比更多的桶支付更多的股息)。
如果您确实需要内存中的数GB地图,那么没有什么可以阻止您实现具有等效64位散列函数的基类。但是,您必须编写自己的Dictionary等效词。
答案 1 :(得分:4)
你做意识到GetHashCode
返回的哈希码用于哈希表中的寻址?使用更大的数据类型将是徒劳的,因为无论如何所有哈希表都较小。其他信息只会被浪费,因为它无法充分利用。
公共哈希表的数量级为几千到几百万。 32位整数足以涵盖这一系列的指数。