2009-02-22 106 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

在採取優化措施時要小心考慮數據結構的特徵。舉一個極端的例子,按排序順序將元素插入到二叉樹中將導致鏈接列表。