簡體   English   中英

具有不同初始容量和負載因子的HashMap的性能

[英]Performance of HashMap with different initial capacity and load factor

這是我的情況。 我使用兩個java.util.HashMap將一些常用數據存儲在Tomcat上運行的Java Web應用程序中。 我知道每個Hashmap的確切條目數。 鍵分別為字符串和整數。

我的問題是,設置初始容量和loadfactor的最佳方法是什么?

我應該將容量設置為等於它將具有的元素數量和負載容量為1.0嗎? 我想在不使用太多內存的情況下獲得絕對最佳性能。 但是,我擔心桌子不能最佳填充。 使用所需的確切大小的表,是否會發生鍵沖突,導致(通常是短暫的)掃描找到正確的元素?

假設(並且這是一個延伸)哈希函數是整數鍵的簡單模5,這並不意味着鍵5,10,15將擊中相同的桶然后導致搜索填充旁邊的桶他們? 更大的初始容量是否會提高性能?

此外,如果有一個比hashmap更好的數據結構,我對此也完全開放。

在沒有完美的數據哈希函數的情況下,並假設這實際上不是真正無關緊要的微優化,我會嘗試以下方法:

假設在大多數情況下HashMap使用的默認負載容量(.75)是一個很好的值。 在這種情況下,您可以使用它,並根據您自己對將要保留的項目數量的知識設置HashMap的初始容量 - 將其設置為初始容量x .75 =項目數(向上舍入)。

如果它是一個更大的地圖,在高速查找非常關鍵的情況下,我會建議使用某種特里而不是哈希映射。 對於長字符串,在大型映射中,通過使用更多面向字符串的數據結構(例如trie),可以節省空間,並且有一段時間。

假設你的哈希函數是“好的”,最好的做法是將初始大小設置為預期的元素數量,假設你可以便宜地得到一個好的估計。 這樣做是個好主意,因為當HashMap調整大小時,必須重新計算表中每個鍵的哈希值。

將負載系數保持在0.75 根據經驗選擇0.75的值作為哈希查找性能和主哈希數組的空間使用之間的良好折衷。 當您將負載系數提高時,平均查找時間將顯着增加。

如果你想深入研究哈希表行為的數學:Donald Knuth(1998)。 計算機程序設計的藝術。 3:排序和搜索(第2版)。 Addison-Wesley出版社。 第513-558頁。 國際標准書號0-201-89685-0。

除非我真的需要,否則我發現最好不要使用默認設置。

Hotspot非常適合為您進行優化。

在任何情況下; 我會使用分析器(Say Netbeans Profiler)來首先測量問題。

我們經常存儲10000個元素的映射,如果你有一個好的equals和hashcode實現(和字符串和整數做!),這將比你可能做的任何負載變化更好。

假設(這是一個延伸)哈希函數是整數鍵的簡單模5

不是。 來自HashMap.java:

static int hash(int h) {
  // This function ensures that hashCodes that differ only by
  // constant multiples at each bit position have a bounded
  // number of collisions (approximately 8 at default load factor).
  h ^= (h >>> 20) ^ (h >>> 12);
  return h ^ (h >>> 7) ^ (h >>> 4);
}

我甚至都不會假裝我明白這一點,但它看起來像是為了處理這種情況。

另請注意,無論您要求的大小,桶的數量也始終為2的冪。

條目以類似隨機的方式分配給存儲桶。 因此,即使您有多個桶作為條目,一些桶也會發生沖突。

如果你有更多的桶,你會有更少的碰撞。 但是,更多的桶意味着在內存中擴散,因此更慢。 通常,0.7-0.8范圍內的負載系數大致是最佳的,因此可能不值得改變。

與以往一樣,在你對這些東西進行微調之前,它可能值得進行分析。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM