关于times33算法

不约而同的,几乎所有的流行的hash map都采用了DJB hash function,俗称“Times33”算法。Perl、Berkeley DB 、Apache、MFC、STL 等等。

times33的算法也很简单,就是不断的乘33。nHash = nHash*33 + *key++;

我没找到什么理论可以说明这种算法的合理性,据说只是通过测试和实践发现这个算法是比较好的。

我把times33和一些其他哈希算法做过比较,times33确实比我找到的其他哈希算法都更快。另外,有人说times33对英文字母效率比较好,处理中文的时候效率就比较低;我对此进行了一些测试,发现times33在处理ascii和中文的时候,性能差异在千分之三以下,我认为这是正常的误差。

哈希算法的比较

《打造最快的Hash表(和Blizzard的对话)》一文里,讲述blizzard如何改良hash表的。在上述哈希算法里面有一段 “seed2 + (seed2 << 5)” 相当于乘以33,其实可以看作是times33算法的变种。我对blizzard这种实现方法的效率存有怀疑。

上述blizzard的哈希算法的核心如下(我给cryptTable赋了最简单的值,而且把dwHashType设为了1):

inline UINT CMyMap::HashKey(LPCTSTR key) const
{int dwHashType = 1;unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;int ch;while(*key != 0){ ch = toupper(*key++);//seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);seed1 = ((dwHashType << 8) + ch) ^ (seed1 + seed2);seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; }return seed1;
}

我进行了一下测试,发现blizzard的哈希算法,分布不如经典的times33算法。

它的分布如下:elements=10000, good=4293 bad2=1786 bad3=528 bad4=109 vbad=22

而经典times33算法的分布是:elements=10000, good=4443 bad2=1775 bad3=501 bad4=107 vbad=15

说明:这是我测试程序的输出,测试的时候,我通过InitHashTable()把bucket个数设为了12007。输出中的elements表示哈希表中一共存放了多少个元素,good表示“只有一个元素”的bucket个数,bad2表示“有两个元素”的bucket个数,bad3表示“有三个元素”的bucket个数,vbad表示“有五个或者五个以上元素”的bucket个数。

经典times33算法如下:

inline UINT CMyMap::HashKey(LPCTSTR key) const
{UINT nHash = 0;while (*key)nHash = (nHash << 5) + nHash + *key++;return nHash;
}

从代码可以很明显的看出,blizzard的这个hash算法的计算工作量也要比经典的times33算法大很多。

我的理解是:这是为了让同一个字符串,可以根据 dwHashType 的不同而计算出不同的独立的hash值。为了实现这个目的,blizzard的这个hash算法在性能上已经付出了一些代价。

哈希表的比较

另外,blizzard这个算法本质上还是把数据放在hash bucket里面,也同样是在每个hash bucket里面有一个list队列。

只不过一般的hash表,在找到hash bucket之后,就逐个的直接比较element;而blizzard的这个hash表,则是用“额外的两个hash值的比较”来代替element的直接比较。孰优孰劣要看具体的应用环境。

考虑到计算三次hash值的工作量,我觉得如果设置一个合适的hash bucket count,blizzard的做法可能还要更慢。(可以参考 引入哈希桶的概念来实现一个哈希表 这篇文章的图解)

上面我做的hash分布测试已经表明,当hash bucket count比elements大20%以上的时候,查找一个element的strcmp调用次数大约是(4443*1+1175*2*1.5+501*3*2+107*4*2.5+15*5*3)/10000=1.2269次,大约是1.2次。(4443个bucket只有一个element,因此一次strcmp就可以确认了。有1175个bucket有两个元素,平均要1.5次strcmp才能找到它。以此类推。)

做1.2次strcmp()和做2次HashKey()相信大家都知道谁比较耗时了。

看来,这个所谓”最快的hash表“似乎有点名不副实呢?还是另有玄机我没看透?

所谓"One-way hash"其实就是不可逆hash,主要是用来加密用的,和速度快不快没什么关系。实际上"One-way hash"为了达到不可逆的目的,通常总是要更慢一些。blizzard是我很喜欢的公司,我也是暴雪的铁杆fans,不过这次似乎有人夸暴雪夸错方向了:)

最后推荐一篇很有趣的文章:http://www.partow.net/programming/hashfunctions/

Times33算法与最快的Hash表相关推荐

  1. 打造最快的Hash表

    打造最快的Hash表 一个简单的问题:有一个庞大的字符串数组,然后给你一个单独的字符串,让你从这个数组中查找是否有这个字符串并找到它,你会怎么做?有一个方法最简单,老老实实从头查到尾,一个一个比较,直 ...

  2. Blizzard经典之打造最快的Hash表

    大学时代,对于Blizzard情有独钟,特别是100M左右的程序,能够打造出来魔兽争霸,简直是叹为观止!一个能在386上运行流畅的游戏,仅仅用了256色的颜色索引表,就打造了其游戏中丰富的视觉感受,从 ...

  3. 从头到尾彻底解析Hash表算法

    从头到尾彻底解析Hash表算法 发布时间: 2013-10-02 10:26  阅读: 25156 次  推荐: 14   原文链接   [收藏]   作者:July.wuliming.pkuoliv ...

  4. 转 从头到尾彻底解析Hash表算法

    出处:http://blog.csdn.net/v_JULY_v.   说明:本文分为三部分内容,     第一部分为一道百度面试题Top K算法的详解:第二部分为关于Hash表算法的详细阐述:第三部 ...

  5. hash表冲突处理方法

    为提高hash表查找性能,除了考虑选择合适的hash表表长和完美的hash函数外,还必须考虑hash表处理冲突的能力.当hash函数对两个不同的数据项产生了相同的hash值时,冲突就产生了.对于冲突的 ...

  6. 哈希(hash)表查找速度为什么那么快?快在哪里了?

    先看数组存储数据是怎么样的. 现在有一个数组,它里面每个单元存储的是数据的地址 这叫指针数组吧,假设它有100个单元 我们称他为p[100] 现在我想把一百个数据(地址)放到里面 我们想把某个数据放到 ...

  7. SCU4438 Censor(审查员) (KMP算法与模拟栈的应用 || HASH表与模拟栈的结合)

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text pp. Her j ...

  8. 一步一步写算法(之hash表)

    [ 声明:版权全部,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] hash表,有时候也被称为散列表.个人觉得,hash表是介于链表和二叉树之间的一种中间结构.链 ...

  9. 《算法导论》之hash表

    Hash表原理不难,难在如何选择表的大小以及hash函数,这个涉及到很多数学的东西,这里就先不详述了,而是先整理下基本概念和一些结论. Hash就是通过函数,将大范围的key值映射到小范围的hash表 ...

最新文章

  1. Linux下autoreconfig命令安装.
  2. 图灵奖得主Judea Pearl 智源大会演讲:从“大数据革命”到“因果革命”
  3. 2014522420145238《信息安全设计基础》实验二
  4. 零元学Expression Blend 4 - Chapter 1 缘起
  5. 数据下载工作笔记三:脚本
  6. jdk与jre的区别 很形象,很清晰,通俗易懂
  7. (转)研究报告:区块链+供应链金融
  8. 提交不了_领导嘲讽程序员代码太过整洁,网友:太矫情,这种代码提交不了
  9. linux was8.5 无法启动wct.sh,WebSphere(was8.5) 在linux集群安装及部署.docx
  10. python gps定位_GPS 测试汇总和python GPS 导航地图实现
  11. junit5 入门系列教程-14-junit5 重复测试(@RepeatedTest)
  12. PDF转CAD格式软件下载及使用教程
  13. Python 批量合并 Excel
  14. “pip-script.py”is not present的问题
  15. 华宇(大连)一面-20190620
  16. Qgis教程11:三维效果
  17. MBA-day18 消元法
  18. 浙大Python 第1章-3 输出“人生苦短,我学Python” (10 分) ---- 过于ez
  19. HTML5期末大作业:电影网站设计——指环王:护戒使者(13页) HTML+CSS+JavaScript
  20. 如何用python制作静摩擦力模拟器 python项目小发明 【安安教具】-【物理】-【静摩擦力】模拟器

热门文章

  1. mysql 非最佳查询_Mysql 查询优化
  2. Mac 安装配置 chromedriver
  3. sql查询时间过长和什么有关系_2020年成人高考成绩查询时间是什么时候?
  4. arduino 蓝牙示例_,arduino 蓝牙例子,
  5. VS2010+OpenMP的简单使用
  6. Java编写程序将数据存入Kafka中
  7. BZOJ1010 [HNOI2008]玩具装箱
  8. 阅读笔记 火球UML大战需求分析4
  9. 对于glut和freeglut的一点比较和在VS2013上的配置问题
  10. [golang note] 工程组织