認識StringBuilder的Capacity自動增加方式

  現在知道動態組字串要用StringBuilder,它的效能會比較好,但一般我們都是直接new出來用,很少去設定它的Capacity,那麼StringBuilder它的預設Capacity是多少?而在我們使用的過程中,它是怎麼自動增加?

  現在知道動態組字串要用StringBuilder,它的效能會比較好,但一般我們都是直接new出來用,很少去設定它的Capacity,那麼StringBuilder它的預設Capacity是多少?而在我們使用的過程中,它是怎麼自動增加?

 

  一般在我們直接New的情況下StringBuilder sb=new StringBuilder(),它的預設Capacity16,每次Append個長度為1的字串,當我們加入的字串長度超過16,它就自動變大,它的Capacity就會變為32,之後就是64,128,256,512….的倍增方式.

Capacity : 16   Length : 0        [預設為16]

Capacity : 32   Length : 17      [第一次Append]

Capacity : 64   Length : 33      [第二次Append]

Capacity : 128 Length : 65     [第三次Append]

Capacity : 256 Length : 129   [第四次Append]

所以每次Length超過Capacity,Capacity就會倍增.

 

  如果我們改變它的預設Capacity20,Append的方式一樣,那它的Capacity變化方式是什麼,是為依照16,32,64,128的固定階級原則增加,還是倍增?

Capacity : 20   Length : 0        [預設為16]

Capacity : 40   Length : 21      [第一次Append]

Capacity : 80   Length : 41      [第二次Append]

Capacity : 160 Length : 81      [第三次Append]

Capacity : 320 Length : 161    [第四次Append]

結論是它會依我們所設定的預設Capacity去倍增.

 

  這次換個角度去想,如果我們不是只Append長度為1的字串,那麼它的Capacity是怎麼變的?所以這次改測試每次都Append一個長度為33的字串.

Capacity : 16   Length : 0        [預設為16]

Capacity : 33   Length : 33      [第一次Append]

Capacity : 66   Length : 66      [第二次Append]

Capacity : 132 Length : 99     [第三次Append]

Capacity : 264 Length : 165   [第四次Append]

  從第一次到到四次Append都沒什麼問題,它都是倍增上去,但從預設到第一次Append,依照之前的實驗結果,應該是16*2=32,因為字串的Length33超過倍增後的Capacity 32,所以Capacity會再倍增32*2=64,但測試結果Capacity卻是33?這之中還有什麼環節不同嗎?

 

那麼再換個Length31來試看看.

Capacity : 16   Length : 0        [預設為16]

Capacity : 32   Length : 31      [第一次Append]

Capacity : 64   Length : 62      [第二次Append]

Capacity : 128 Length : 93     [第三次Append]

Capacity : 256 Length : 155   [第四次Append]

這次就沒有問題了,是從16直接倍增上來.

 

  比較了一下這兩個有什麼差別?前一個測試Append的字串長度為33一次跨了兩階,也就是16倍增後是32,但仍不夠儲存這個長度.所以就直接依實際字串長度來設定Capacity,而第二個測試並沒有跨兩階,再驗證一下這個想法是否正確,如果第一次Append Length=31,第二次為34,會有什麼不同.是否跨兩階就不會是倍增,而是直接依實際長度.

Capacity : 16   Length : 0        [預設為16]

Capacity : 32   Length : 31      [第一次Append]

Capacity : 65   Length : 65      [第二次Append]

看起來好像真的是如此

 

那改一下第二次Append的長度為3,那麼應該就是64.

Capacity : 16   Length : 0        [預設為16]

Capacity : 32   Length : 31      [第一次Append]

Capacity : 64   Length : 34      [第二次Append]

實驗結果,果然是如此.

 

最後再看一下,如果是字串長度跨兩階以上,是否也是一樣的方式,所以第二次Append的長度為200.

Capacity : 16   Length : 0        [預設為16]

Capacity : 32   Length : 31      [第一次Append]

Capacity : 231 Length : 231    [第二次Append]

不失所望的,確實是依實際的字串長度.

 

綜合以上的測試結論 :

Capacity預設是 16

如果Append的字串長度沒有跨兩階,它會是以Capacity倍增的方式.

如果Append的字串長度跨兩階以上,它會是以實際的Length來設定Capacity.

 

基本上是建議在知道將使用的Capacity量時,最好是設定Capacity,如果不知道,那就看取得將使用的Capacity量所付出的Cost是否值得,比如說,執行一些判斷動作後,才知道要設多少Capacity,結果只有幾百筆,那就大可少掉這個動作,我們已經知道Capacity自動長大的方式,異動的次數並不多.

 

希望這樣的實驗結果,能有助大家判斷什麼時候要設Capacity~