首 先算得key得hashcode值,然後跟陣列的長度-1做一次「與」運算(&)。看上去很簡單,其實比較有玄機。比如陣列的長度是2的4次方, 那麼hashcode就會和2的4次方-1做「與」運算。很多人都有這個疑問,為什麼hashmap的陣列初始化大小都是2的次方大小時,hashmap 的效率最高,我以2的4次方舉例,來解釋一下為什麼陣列大小為2的冪時hashmap訪問的效能最高。 看下圖,左邊兩組是陣列長度為16(2的4次方),右邊兩組是陣列長度為15。兩組的hashcode均為8和9,但是很明顯,當它們和1110「與」的 時候,產生了相同的結果,也就是說它們會定位到陣列中的同乙個位置上去,這就產生了碰撞,8和9會被放到同乙個鍊錶上,那麼查詢的時候就需要遍歷這個鏈 表,得到8或者9,這樣就降低了查詢的效率。同時,我們也可以發現,當陣列長度為15的時候,hashcode的值會與14(1110)進行「與」,那麼 最後一位永遠是0,而0001,0011,0101,1001,1011,0111,1101這幾個位置永遠都不能存放元素了,空間浪費相當大,更糟的是 這種情況中,陣列可以使用的位置比陣列長度小了很多,這意味著進一步增加了碰撞的機率,減慢了查詢的效率!所以說,當陣列長度為2的n次冪的時候,不同的key算得得index相同的機率較小,那麼資料在陣列上分布就比較均勻,也就是說碰撞的機率小,相對的,查詢的時候就不用遍歷某個位置上的鍊錶,這樣查詢效率也就較高了。說到這裡,我們再回頭看一下hashmap中預設的陣列大小是多少,檢視源**可以得知是16,為什麼是16,而不是15,也不是20呢,看到上面 annegu的解釋之後我們就清楚了吧,顯然是因為16是2的整數次冪的原因,在小資料量的情況下16比15和20更能減少key之間的碰撞,而加快查詢 的效率。 3、
當hashmap中的元素越來越多的時候,碰撞的機率也就越來越高(因為陣列的長度是固定的),所以為了提高查詢的效率,就要對hashmap的陣列進行 擴容,陣列擴容這個操作也會出現在arraylist中,所以這是乙個通用的操作,很多人對它的效能表示過懷疑,不過想想我們的「均攤」原理,就釋然了, 而在hashmap陣列擴容之後,最消耗效能的點就出現了:原陣列中的資料必須重新計算其在新陣列中的位置,並放進去,這就是resize。
那麼hashmap什麼時候進行擴容呢?當hashmap中的元素個數超過陣列大小*loadfactor時,就會進行陣列擴容,loadfactor的 預設值為0.75,也就是說,預設情況下,陣列大小為16,那麼當hashmap中元素個數超過16*0.75=12的時候,就把陣列的大小擴充套件為 2*16=32,即擴大一倍,然後重新計算每個元素在陣列中的位置,而這是乙個非常消耗效能的操作,所以如果我們已經預知hashmap中元素的個數,那 麼預設元素的個數能夠有效的提高hashmap的效能。
比如說,我們有1000個元素new hashmap(1000), 但是理論上來講new hashmap(1024)更合適,不過上面annegu已經說過,即使是1000,hashmap也自動會將其設定為1024。 但是new hashmap(1024)還不是更合適的,因為0.75*1000 < 1000, 也就是說為了讓0.75 * size > 1000, 我們必須這樣new hashmap(2048)才最合適,既考慮了&的問題,也避免了resize的問題。
影響軟體效能的因素
軟體效能是軟體的一種非功能特性,它關注的不是軟體是否能夠完成特定的功能,而是在完成該功能時展示出來的及時性。由於感受軟體效能的主體是人,不同的人對於同樣的軟體能有不同的主觀感受,而且不同的人對於軟體效能關心的視角也不同。目前,大部分系統都是為多使用者 跨地域 多部門機構提供服務的,目前一般中小企業的...
影響MySql效能的因素
哪些資料不適合存在資料庫中?流水佇列資料 一些系統中,每次交易,存放等都會產生流水佇列資料,資料量非常龐大 那些資料存放在cache 快取 中?減少資料庫的互動次數 在這裡我們列舉乙個n 1的問題,總所周知,在使用mybatis的時候當a物件中包含b物件 也就是乙個物件存在乙個關聯物件 a物件列表中...
影響HBase insert效能的幾個因素
在使用hbase put api的時候,有幾個會影響效能的因素。1.put list size hbase的put支援單條插入,也支援批量插入。2.autoflush autoflush指的是在每次呼叫hbase的put操作,是否提交到hbase server。預設是true,每次會提交。如果此時是...