HashMap的loadFactor为什么是0.75

HashMap中loadFactor用于计算扩容的阈值。扩容意味着空间(resize)和时间(rehash)的开销,不扩容则会导致使用(查询、操作)成本快速增长,平衡时间和空间是一门艺术。


问题

    JDK 1.7

As a general rule, the default load factor (.75) offers a good tradeoff between time and space costs. Higher values decrease the space overhead but increase the lookup cost (reflected in most of the operations of the HashMap class, including get and put). The expected number of entries in the map and its load factor should be taken into account when setting its initial capacity, so as to minimize the number of rehash operations. If the initial capacity is greater than the maximum number of entries divided by the load factor, no rehash operations will ever occur.

    JDK 1.8

Ideally, under random hashCodes, the frequency of nodes in bins follows a Poisson distribution with a parameter of about 0.5 on average for the default resizing threshold of 0.75, although with a large variance because of resizing granularity. Ignoring variance, the expected occurrences of list size k are (exp(-0.5) pow(0.5, k) / factorial(k)). The first values are:

0: 0.60653066

1: 0.30326533

2: 0.07581633

3: 0.01263606

4: 0.00157952

5: 0.00015795

6: 0.00001316

7: 0.00000094

8: 0.00000006

jdk1.7中的注释中指出了default_loadFactor 为 0.75是时间与空间的tradoff,但并未提到该数值是怎么得来的。

jdk1.8中的注释中提到随机的hashCodes命中特定bin的频率在缺省阈值为0.75时,服从参数λ=0.5的泊松分布,亦未解释0.75的来源。


基础

为了解释0.75的来源,需要一些基础工具做铺垫。

    **Hash function**

A hash function is any function that can be used to map data of arbitrary size to data of fixed size. The values returned by a hash function are called hash values, hash codes, digests, or simply hashes. One use is a data structure called a hash table, widely used in computer software for rapid data lookup. Hash functions accelerate table or database lookup by detecting duplicated records in a large file. An example is finding similar stretches in DNA sequences. They are also useful in cryptography. A cryptographic hash function allows one to easily verify that some input data maps to a given hash value, but if the input data is unknown, it is deliberately difficult to reconstruct it (or equivalent alternatives) by knowing the stored hash value. This is used for assuring integrity of transmitted data, and is the building block for HMACs, which provide message authentication.

密码学中所用的安全哈希函数(cryptographic hash function)和查找/存储用的哈希遵从不同的设计原则,除了数据压缩和快速计算,安全哈希还满足抗原象性、抗第二原象性和抗碰撞性。

    **Hash Collision**

In computer science, a hash collision or hash clash is a situation that occurs when two distinct inputs into a hash function produce identical outputs.

All hash functions have potential collisions, though with a well-designed hash function, collisions should occur less often (compared with a poorly designed function) or be more difficult to find. In certain specialized applications where a relatively small number of possible inputs are all known ahead of time it is possible to construct a perfect hash function which maps all inputs to different outputs. However, many hash functions, including most cryptographic hash functions, produce a fixed size output from an arbitrarily long message. In such a design, there will always be collisions, because any given hash has to correspond to a very large number of possible inputs.

哈希碰撞及解决方案见这里

    **Distribution**

伯努利分布:一次实验中,事件A发生的概率为p ,不出现的概率为q=1-p
P(X=1)=p, P(X=0)=1-p,0<p<1
二项分布:在只有两个结果的n次独立的伯努利试验中,所期望的结果出现次数的概率。
b(x,n,p)=C^x_n p^xq^{n-x}
泊松分布:描述单位时间内事件发生的概率。
P(X=k) = \frac{λ^{k}}{k!}e^{-λ}


分析

一次实验中key落在某个bucket的概率为 p=\frac{1}{s},hash结果只与输入有关( random hashCodes),多次hash可视为相互独立。即bucket为空的概率服从二项分布:
P(0)=C^0_n*(\frac{1}{s})^0*(1- \frac{1}{s})^{n-0} =(1-\frac{1}{s})^n
因此bucket在如下条件下可能为空(P(0)=0.5,如JDK1.8中提到的):
0.5=(1-\frac{1}{s})^n

log(\frac{1}{2})=nlog(1-\frac{1}{s}))

n= \frac {log(2)}{log(\frac{s}{s-1})}

进行\frac {log(2)}{log(\frac{s}{s-1})}次hash后,bucket为空的概率为0.5,即如JDK1.8中所指单位时间内key落在某bucket的概率服从λ=0.5的泊松分布。

更进一步,当s趋于无穷时,扩容阈值\frac{n}{s}快速逼近log(2):
\lim_{s→+∞}\frac{ \frac{log(2)}{log\frac{s}{s - 1}}}{s}

=log(2)\lim_{ s→+∞}\frac{(s^{-1})'}{log(s)'-log(s-1)'}

=log(2)\lim_{ s→+∞}\frac{s-1}{s}

=log(2)

其中log(2) ≈ 0.69314718055994530941723212145818,理论上阈值定为log(2)更能平衡时间与空间的开销。


结论

  1. default_loadFactor = 0.75和泊松分布没有直接关系。泊松分布描述的是单位时间内bucket中node个数的概率,服从泊松分布是HashMap采用Chaining解决哈希冲突的性质决定的。
  2. default_loadFactor = 0.75和泊松分布的参数λ=0.5有直接关系。λ是单位时间(或单位面积)内随机事件的平均发生次数,此处为bucket是否为空的期望E(X)=np为0.5。
  3. default_loadFactor取log(2)理论上更合适,但考虑HashMap的default_capacity = 16,扩容规则为 n = 2*n,无疑 threshold = 2^n * 0.75 便于计算且易于实现。

看到这儿了,留个呗。


参考文献

  1. 王小云, 于红波. 密码杂凑算法综述[J]. 信息安全研究, 2015, v.1;No.1(01):19-30.
  2. https://stackoverflow.com/questions/10901752/what-is-the-significance-of-load-factor-in-hashmap
  3. https://blog.csdn.net/kjfcpua/article/details/44238757
  4. https://www.jianshu.com/p/64f6de3ffcc1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容