2009-02-19 119 views
12

確定的預期數量,這裏是我的情況:選擇一個HashSet的初始容量與獨特的價值觀和插入

我有美國的數組,其中可能包含重複。爲了擺脫重複,我可以將它們全部添加到Set。

但是,當我創建Set時,它需要定義初始容量和加載因子,但是應該設置什麼?

從谷歌上搜索,我想出了:

String[] allStates = getAllStates(); 
Set<String> uniqueStates = new HashSet<String>(allStates.length, 0.75); 

的問題,這一點,是allStates可在1個5000狀態之間anwhere包含。因此,該設置將具有超過5000的容量,但僅包含最多50個。

因此,可選地設置該設置的最大尺寸可以被設置爲狀態的最大數目,並且負載因子爲1。

我想我的問題確實在:

  • 你應該怎麼設置的初始容量是當你不知道有多少項目是在設置?
  • 當它可以包含的最多數量是50時,它設置的是否真的很重要?
  • 我應該甚至擔心它嗎?

回答

12

假設你知道不會有超過50個州(你的意思是美國國?),在

Set<String> uniqueStates = new HashSet<String>(allStates.length, 0.75); 

報價肯定是不對的。我建議你選擇50/0.75 = 67的初始容量,或者68的安全容量。

我也覺得有必要指出的是,你可能得太多強烈的這個。將陣列列表從第16個調整到第64個不會給您帶來顯着的性能提升,除非在該程序中性能最關鍵的部分是正確的。

所以最好的答案可能是使用:

new HashSet<String>(); 

這樣一來,你就不會在一年後和益智回來了,爲什麼你選擇了這種奇怪的構造函數的參數。

7

使用constructor您不需要指定這些值,然後選擇合理的默認值。

+0

現貨。擔心只有在成爲問題時的性能 – basszero 2009-02-19 11:51:47

+2

那麼,明智地避免性能問題,但不要微觀優化。 – 2009-02-19 12:14:30

0

做個很好的猜測。沒有硬性規定。如果你知道有可能說10-20個州,我會從這個數字開始(20)。

1

安全的賭注是去一個太小的大小。

由於調整大小是通過指數增長算法改善的(請參閱幾周前的stackoverflow播客),小事不會花費太多。如果你有很多套(幸運的話),那麼如果它們超大,那麼它就會對性能產生影響。

加載因子是一個棘手的問題。我建議把它留在默認狀態。我明白:在0.70f以下,你會讓陣列太大,因此速度會變慢。超過0.80f,你會開始發生許多重大沖突。推測探測算法將需要比桶算法更低的負載因子。

還要注意的是,「初始容量」意味着什麼略有不同似乎大多數人認爲。它指的是數組中的條目數。要獲得多個元素的確切容量,請除以期望的負載係數(並適當舍入)。

0

我第二Zarkonnen。你最後的問題是最重要的。如果這種情況發生在應用程序的熱點中,則可能值得努力查看它並嘗試優化,否則CPU週期比燒燬自己的神經元便宜。

0

如果您要優化這個 - 可能適合這樣做 - 您的一些決定取決於您期望數組有多少重複項。

  • 如果有非常多的重複,你會希望有一個較小的初始容量 。迭代時,大而稀疏的哈希表很糟糕。

  • 如果預計不會有太多重複項,您需要 作爲初始容量,以便整個陣列可以在沒有調整大小的情況下適應。

我的猜測是你想要後者,但這是值得考慮的事情,如果你追求這一點。

1

首先,我要說的是,在你的情況下,你肯定會推翻它。但是,有可能出現這樣的情況,即人們想要正確地做到這一點。所以這裏是我的理解:

1)您可以在您的HashSet中保存的項目數=初始容量x加載因子。所以如果你想能夠持有n件物品,你需要做Zarkonnen做的事情,並用負載因子除n。

2)在封面下,初始容量四捨五入爲per Oracle tutorial的二次方。

3)如Tom Hawtin - tackline所述,載荷係數應不大於.80以防止過度碰撞。

如果您只接受默認值(初始容量= 16,加載因子= .75),您最終會將設置的大小加倍3倍。 (初始最大容量= 12,首先增加容量32和最大容量24(32 * .75),第二次增加容量64和最大容量48(64 * .75),第三次增加容量128和最大容量96(128 * .75)。)

爲了使您的最大尺寸接近50,但保持儘可能小的設置,請考慮64的初始容量(2的冪)和0.79或更大的負載係數。 64 * .79 = 50.56,所以你可以在那裏得到所有50個州。指定32 <初始容量< 64將導致初始容量四捨五入爲64,因此這與先前指定64相同。指定初始容量< = 32將導致尺寸增加。使用負載因子< .79也會導致尺寸增加,除非您的初始容量大於64.因此,我的建議是指定初始容量= 64和負載因數= .79。