我应该为一个非常大的数据集使用`HashSet`或`TreeSet`吗?

时间:2015-08-04 04:27:06

标签: java performance hashset treeset

我需要在数据结构中存储2到1,500万个帐户(长度为String),以便查找和检查唯一性。最初我计划将它们存储在HashSet中,但我怀疑由于哈希冲突导致查找的速度会很慢,并且最终会比TreeMap慢(使用二进制搜索)。

不需要对数据进行排序。我正在使用Java 7.我有64G系统,48G专用于此应用程序。

此问题与HashSet and TreeSet performance test不重复,因为该问题与Set 添加元素的效果有关,此问题与的效果有关检查现有Set是否有重复值。

2 个答案:

答案 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>。性能建议和构造函数参数仍然适用。

进一步阅读:HashSet and TreeSet performance test

答案 1 :(得分:2)

当我们尝试使用适当的初始化参数在HashMap中存储5000万条记录时,插入开始减速,特别是在3500万条记录之后。更改为TreeMap提供了持续的插入和检索性能。

观察:对于大型输入集,TreeMap将提供比HashMap更好的性能。对于较小的集合,HashMap当然会提供更好的性能。