为什么String.GetHashCode()在32位和64位版本的CLR中实现不同?

Ili*_*ian 20 c# clr hash

string.GetHashCode()的32位和64位版本之间的差异背后的技术原因是什么?

更重要的是,为什么64位版本在遇到NUL字符时似乎终止了它的算法?例如,在64位CLR下运行时,以下表达式都返回true.

"\0123456789".GetHashCode() == "\0987654321".GetHashCode()
"\0AAAAAAAAA".GetHashCode() == "\0BBBBBBBBB".GetHashCode()
"\0The".GetHashCode() == "\0Game".GetHashCode()
Run Code Online (Sandbox Code Playgroud)

当我们将这样的字符串用作Dictionary中的键时,这种行为(bug?)表现为性能问题.

Kob*_*obi 11

这看起来像微软无法修复的已知问题:

正如你所提到的那样,对于某些程序来说这将是一个重大变化(即使它们不应该真的依赖于此),这种风险被认为太高而无法在当前版本中解决这个问题.

我同意这将在默认的Dictionary <String,Object>中导致的冲突率将由此膨胀.如果这会对您的应用程序性能产生负面影响,我建议尝试使用一个带有IEqualityComparer的Dictionary构造函数来解决它,以便您可以提供更合适的GetHashCode实现.我知道这不太理想,并希望在未来的.NET Framework版本中修复此问题.

源:Microsoft Connect - String.GetHashCode忽略x64运行时中第一个空字节之外的字符串中的任何字符

  • 我不明白任何这种"突破性变化"的借口.GetHashCode源代码中的注释清楚地表明哈希的计算从未被认为是永久性的.即使一些傻瓜开始依赖它,它们也已经存在问题,因为哈希码是依赖于架构的.这是一个MS错误,应该修复.自2010年以来,这一直在减慢我的哈希表.是的,我确实需要将有时 - '\ 0'字节转换为字符串,因为字符串是.Net中最快的可变大小字典键! (3认同)