Understanding GetHashCode, 理解GetHashCode

问题的引出:

最近在阅读SSCLI的BCL的代码, 解析Hash过程自然是至关重要了 :)

本文需要的基础

1. 知道Hashtable的概念和过程

2. 知道类型系统

不知道Hashtable?

Hashtable, 或者Hasmap(中文名称: 散列表)是一种快速定位的数据结构。他能提供期望O(1)的时间复杂度,然而实际上性能上会有所偏差,因为需要进行Hash,取模,比较这样的运算,而且还跟Hashtable的结构存储有关系, 但是最多也就是O(n)的复杂度, 这个跟我们选取的Hash函数有关系

Lucifer的两篇文章写的很好: 数据结构 : Hash Table [I] , 数据结构 : Hash Table [II]

您也可以去看看《算法导论》第11章 - 散列表

什么是GetHashCode?

GetHashCode为具体的类型提供Hash函数实现 [FROM MSDN]. 在实现具体的类型时,对于GetHashCode的重载则提供了一个自定义的Hash实现, 这样保存在集合中时则提供唯一的Hash值.

那既然是提供Hash函数实现,那.Net哪些类使用这些Hash函数呢?

Hashtable, Dictionary, NameValueCollection NameObjectCollection, HybirdDictionary, ListDictionary 等等

探索GetHashCode()

我们知道Object是所有类的结构于是对GetHashCode的探索是从Object开始了

clr/src/bcl/system/object.cs

image

按照注释是返回同步锁的值,那好,做个测试就好

测试思路: 用一个类型继承自Object, 但是不重写GetHashCode, 这样在Debug的时候就可以方便的通过这个类型得到地址

image

这是运行测试的代码和结果,再用WINDBG进去看看  哈哈

image

既然Object是这样,那基本类库(BCL, Basic Class Library)中的值类型和引用类型呢?

值类型:

基本类型 int, float, double, bool, demical, byte, char, Enum

int32:

image

float:

image

Double:

image

Boolean:

image

image

引用类型:

String

image

正如 数据结构 : Hash Table [I] 所言,这是一个经验公式,当然了这个并不能保证任意两个字符串的HashCode一样, 这里有一篇来自BCLTeam的说明

而不能一致则会涉及到碰撞检测的过程. 请查看数据结构 : Hash Table [II]. Rotor 2源码与文中所述一致,有兴趣的读者也可以去看看 :)

DateTime:

image

GUID:

image

基本上作为某种值的类,都重写了GetHashCode

用户定义的值与类呢?

image

没有默认的实现,就会调用Object.GetHasCode方法得到SyncBlockIndex

对于类我用WINDBG进去看看得到的数据反而不一致,而后DEBUGGING ROTOR得到的结果不对, 在对于Class的实现中,利用了Thread的Hash实现,而后利用产生的随机数得到了一个随机的Hash数

感兴趣的朋友可以去看看: (clr\src\vm\comobject.cpp) INT32 ObjectNative::GetHashCodeEx(Object *objRef)

用于应用的结论

GetHashCode不能用于比较相等

如果需要将定义的类型作为Hash索引,需要重写GetHashCode

posted on 2008-12-13 00:12  xwang  阅读(3130)  评论(8编辑  收藏  举报

导航