我需要在数据结构中存储2到1,500万个帐户(长度为String
),以便查找和检查唯一性。最初我计划将它们存储在HashSet
中,但我怀疑由于哈希冲突导致查找的速度会很慢,并且最终会比TreeMap慢(使用二进制搜索)。
不需要对数据进行排序。我正在使用Java 7.我有64G系统,48G专用于此应用程序。
此问题与HashSet and TreeSet performance test不重复,因为该问题与向Set
添加元素的效果有关,此问题与的效果有关检查现有Set
是否有重复值。
答案 0 :(得分:12)
如果您的200万到1500万条记录中有48 GB的专用内存,那么最好的选择可能是使用HashMap<Key, Record>
,其中您的密钥为Integer
或{{1}根据您的要求。
只要您为String
提供足够的内存并具有适当的加载因子,就可以完成哈希冲突。
我建议使用以下构造函数:Map
(比预期的记录数多30% - 这些记录将new HashMap<>(13_000_000);
的实现自动扩展到HashMap
个单元格)。
告诉您的应用程序,此2^24
将从一开始就非常大,因此在填充时不需要自动增长。
Map
对其成员使用HashMap
访问时间,而O(1)
使用TreeMap
查询时间,但内存效率更高,并且不会#&# 39;需要一个聪明的散列函数。但是,如果您使用O(log n)
或String
键,则无需担心设计散列函数,并且常量时间查找将是一项巨大的改进。此外,Integer
/ TreeMap
的另一个优势是排序顺序,您声明自己并不关心;使用TreeSet
。
如果列表的唯一目的是检查唯一帐号,那么我上面说的所有内容仍然是正确的,但正如您在问题中所述,您应该使用HashMap
,而不是HashSet<String>
。性能建议和构造函数参数仍然适用。
答案 1 :(得分:2)
当我们尝试使用适当的初始化参数在HashMap中存储5000万条记录时,插入开始减速,特别是在3500万条记录之后。更改为TreeMap提供了持续的插入和检索性能。
观察:对于大型输入集,TreeMap将提供比HashMap更好的性能。对于较小的集合,HashMap当然会提供更好的性能。