除了this quite old post之外,我还需要一些能够使用基元并为包含HashSet
Integers
Set<Integer> set = new HashSet<Integer>();
的{{1}}的应用程序提供加速的东西:
TIntHashSet
所以人们提到像Guava,Javalution,Trove这样的图书馆,但是在基准和绩效结果方面没有完美的比较,或者至少是来自良好体验的良好答案。从我看到许多人推荐Trove的HashMap
,但其他人说它不是那么好;有人说Guava是超级冷却和可管理的,但我不需要美观和可维护性,只需时间执行,所以Python的样式番石榴回家:) Javalution?我去过这个网站,看起来对我来说太老了,因而很古怪。
图书馆应提供最佳的可实现时间,记忆无关紧要。
查看“Thinking in Java”,可以创建以int[]
为键的自定义HashSet
。所以我希望看到与HashSet<Integer>
类似的内容,或者只是下载并使用一个了不起的库。
编辑(以回应以下评论)
所以在我的项目中,我从大约50个HashSet<Integer>
集合开始,然后我调用一个函数大约1000次,内部创建多达10个add()
集合。如果我更改初始参数,则数字可能会以指数方式增长。我只在这些集合中使用contains()
,clear()
和HashSet
方法,这就是他们被选中的原因。
现在我将找到一个实现Integer
或类似内容的库,但是由于自动装箱HashSet
开销而且可能是我不知道的其他东西,它会更快地完成。事实上,我正在使用整数,因为我的数据会存入并存储在那些{{1}}中。
答案 0 :(得分:3)
Trove是一个很好的选择。
它比泛型集合快得多的原因是内存使用。
java.util.HashSet<Integer>
在内部使用java.util.HashMap<Integer, Integer>
。在HashMap
中,每个对象都包含在Entry<Integer, Integer>
中。这些对象在实际的哈希表中实际整数+4个字节的Entry
+ 16个字节估计需要24个字节。这产生了44个字节,而不是Trove中的4个字节,高达11倍的内存开销(请注意,主表中未占用的entires在实践中会产生较小的差异)。
另见这些实验:
http://www.takipiblog.com/2014/01/23/java-scala-guava-and-trove-collections-how-much-can-they-hold/
答案 1 :(得分:1)
看看High Performance Primitive Collections for Java (HPPC)。它是一种替代品,成熟且精心设计以提高效率。请参阅JavaDoc以了解IntOpenHashSet。
答案 2 :(得分:0)
您是否尝试在创建HashSet时使用初始容量和加载因子参数?
初始容量,正如您所想,是指空哈希集在创建时的大小,而loadfactor是决定何时增长哈希表的阈值。通常,您希望保持使用的存储桶和总存储桶之间的比率低于三分之二,这被认为是在哈希表中实现良好稳定性能的最佳比率。
Dynamic rezing of a hash table
基本上,尝试设置一个适合您需求的初始容量(以避免在哈希表增长时重新创建和重新分配哈希表的值),以及摆弄加载因子直到找到最佳位置
可能对于您的特定数据分布和设置/获取值,较低的负载因子可能有所帮助(几乎不会更高,但您的milage可能会有所不同)。