不同初始容量和负载因子下HashMap的java性能
这是我的情况。我正在使用两个java。util。HashMap将一些常用数据存储在Tomcat上运行的Java web应用程序中。我知道每个Hashmap的确切条目数。键将分别是字符串和int
我的问题是,设置初始容量和负载系数的最佳方法是什么
我应该将容量设置为它将拥有的元素数量,并将负载容量设置为1.0吗?我希望在不占用太多内存的情况下获得绝对最佳的性能。然而,我担心这张桌子不够满。有了所需的精确大小的表,会不会出现键冲突,导致(通常很短)扫描以找到正确的元素
假设(这是一个延伸)散列函数是整数键的简单mod 5,这难道不意味着键5、10、15将命中同一个存储桶,然后导致搜索填充它们旁边的存储桶吗?较大的初始容量会提高性能吗
此外,如果有比hashmap更好的数据结构,我也完全愿意这样做
# 1 楼答案
如果您的数据没有一个完美的哈希函数,并且假设这不是一个真正无关紧要的微观优化,我会尝试以下方法:
假设HashMap使用的默认负载容量(.75)在大多数情况下都是一个好值。在这种情况下,您可以使用它,并根据您自己对HashMap将容纳多少项的了解来设置HashMap的初始容量——将其设置为初始容量x.75=项数(四舍五入)
如果它是一个更大的映射,在高速查找非常关键的情况下,我建议使用某种trie而不是哈希映射。对于大型映射中的长字符串,可以通过使用更面向字符串的数据结构(如trie)来节省空间和时间
# 2 楼答案
条目以类似随机的方式分配给bucket。因此,即使你有和条目一样多的bucket,其中一些bucket也会发生冲突
如果你有更多的桶,你会有更少的碰撞。然而,更多的存储桶意味着在内存中展开,因此速度较慢。一般来说,0.7-0.8范围内的负载系数基本上是最佳的,因此可能不值得更改
和以往一样,在你对这些东西进行微调之前,可能值得分析一下
# 3 楼答案
我发现最好不要乱动默认设置,除非我真的需要
Hotspot在为您进行优化方面做得很好
无论如何;我会首先使用一个探查器(比如Netbeans探查器)来测量问题
我们通常会存储包含10000个元素的映射,如果你有一个好的equals和hashcode实现(字符串和整数都有!)这将比您可能进行的任何负载更改都要好