2009-02-22 104 views
4

是否有一种方法可以通过指定项目的顺序来优化java.util.Collection中插入的速度?在java.util.Map/Set中优化插入速度

例如

java.util.Set<String> set = java.util.TreeSet<String>(); 

将这种解决方案:

set.add("A"); 
set.add("B"); 
set.add("C"); 
set.add("D"); 
set.add("E"); 

比这一个(随机顺序)快?

set.add("E"); 
set.add("D"); 
set.add("C"); 
set.add("A"); 
set.add("B"); 

(和其他收藏品一样的问题:HashMap中,hastable ...)

感谢

回答

3
red-black tree

插入时间(这是用来实现Java的TreeSet/TreeMap)保证最差情况是O(log n)。如果项目按照特定的顺序,它可能会更快,但我不确定那会是什么(可能预先排序会最快?)。

插入散列表是O(1)(恒定时间)操作。插入的主要工作是计算hashcode


编辑:Starblue建议预先排序可能会产生最坏情况的表现,所以你可以尝试随机顺序。

+0

预排序通常会导致很多不平衡,所以很可能是最糟糕的情况。 – starblue 2009-02-22 18:17:26

+0

我同意,如果你想加快速度,最好的办法是对列表进行排序,找到中位数,然后从中位数的两个方向插入。在这一点上,没有必要重新排序子树。 – Nick 2009-02-22 18:22:10

+0

但是分类需要比以后获得更多的时间。最后这是所有无用的微型优化。 – starblue 2009-02-22 18:50:46

2

在基于哈希的集合和基于树的集合之间自然存在巨大差异。

基于树的插件受益于用于插入的元素排序(例如,字符串之间的比较),所以当您有可比较的对象(如字符串)时,最好使用它们。 TreeSet/TreeMap /等。在标准集合中应该是平衡的(红黑树),所以插入顺序无关紧要。如果它不平衡,那么插入顺序很重要,因为你最终可能会得到一个链而不是一棵树。

在哈希表中,加载因子和哈希函数决定了一切,但如果你正在处理字符串,你甚至可以更好地不用哈希值。

如果你需要一组包含重叠字符串的字符串,Trie的内存效率会更高,但我认为库中没有一个字符串。

6

不适用于java.util.Map和java.util.Set,因为它们是接口,并且有不同的实现。

对于具体的实现它不是一个有价值的优化。如果您在性能方面遇到问题,请选择更适合的实施方案,或者重新考虑需要存储的内容和方式。

将5000个随机数插入HashSet需要大约一毫秒的时间,因此您需要插入多少个元素才能使这种优化变得有价值?

1

在采取优化措施时要小心考虑数据结构的特征。举一个极端的例子,按排序顺序将元素插入到二叉树中将导致链接列表。