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