我刚刚注意到,我从对象中获取不同的哈希码,具体取决于是否为x86或64构建。我能做到这一点吗?

问题描述:

我注意到哈希码,我从其他对象得到了分别不同的,当我建立了x86或x64。 到现在为止,我已经实现了我的大部分自己的散列函数是这样的:我刚刚注意到,我从对象中获取不同的哈希码,具体取决于是否为x86或64构建。我能做到这一点吗?

int someIntValueA; 
int someIntValueB; 

const int SHORT_MASK = 0xFFFF; 
public override int GetHashCode() 
{ 
    return (someIntValueA & SHORT_MASK) + ((someIntValueB & SHORT_MASK) << 16); 
} 

将在长期存储的值,并获得从该散列码给我一个更广泛的范围内,以及在64位系统上,或这是一个坏主意吗?

public override int GetHashCode() 
{ 
    long maybeBiggerSpectrumPossible = someIntValueA + (someIntValueB << 32); 
    return maybeBiggerSpectrumPossible.GetHashCode(); 
} 
+0

它不会给你更大的范围,因为你仍然返回一个'int'。 – Ryan

+0

@Ryan这就是我问的问题:是int总是和int.32在c#中或它成为int64/long在某些情况下? – user3488765

+1

这不是你问的问题。这个问题的答案是:在C#中,int是Int32的同义词,故事结束。一个指针大小的整数是'IntPtr',它们不允许你在C#中进行数学运算。 –

不,那将是差远了。

假设你的INT值通常在很短的范围:-30000和+30000之间。并且进一步假设他们中的大部分接近中间,例如在0和1000之间。这很典型。随着你的第一个散列码你所有两个整数到散列码的位,他们不互相干扰;典型条件下的碰撞次数为零。

但是当你用长做你的绝招,那你靠什么长期执行的GetHashCode确实,这与低32位异或的高32位。所以你的新实现只是编写int1^int2的缓慢方式。在典型的情况下,它几乎全部为零,因此碰撞到处都是。

你的建议将不会做任何事情,任何更好的(完全相反)的方法。

但是......

SpookyHash例如被设计为在64位系统中尤其迅速开展工作,因为工作了笔者在思考数学的时候这将是快速64位系统上,xxHash有32个位和64位变体,旨在分别以更好的速度为32位和64位计算提供可比较的散列质量。

利用不同的算术运算在不同机器上的不同表现的总体思路是一个有效的。

只要这些额外的位进入后续操作,并且您在散列计算中使用较大的中间存储的一般想法也是有效的

因此,在一个水平很一般,答案是肯定的,即使您的特定实现不与才能通过。

现在,在实践中,当你坐下来写一个哈希码实现你应该担心这一点?

那么它依赖。一段时间以来,我非常乐于使用像SpookyHash这样的算法,当散列基于大量的源数据时,它的表现非常好(甚至在32位系统上)。但另一方面,它可能会更好,尤其是在使用较小的基于散列的集合和字典时,要慢得令人尴尬。所以没有一个解决所有问题的答案。只需两个输入整数,你的初始解决方案很可能会胜过xxHash或SpookyHash等超级雪崩算法。也许你可以做的更好,如果你也有一个>> 16旋转,而不是移(有趣的事实,有些紧张是为优化),但我们不认为在所有的涉及64 VS 32位版本。

在64位和32位采用不同的方法确实发现了很大的可能改进的情况是需要混合大量数据的情况下,尤其是如果它处于可扩展形式(如stringbyte[] ),根据框架,您可以通过long*int*访问。因此,通常你可以忽略比特性的问题,但是如果你发现自己在思考“这个哈希码必须经过这么多东西才能得到答案;我可以做得更好吗?”那么也许是时候考虑这些事情了。