2016-05-16 81 views
3

我在看Apache Commons的StringUtils.join方法的實現,偶然發現了一條我認爲是性能的線路,但我不明白他們爲什麼按照它的方式做到了這一點,值。瞭解StringUtils.join性能決策

這裏的實現:

public static String join(Object[] array, String separator, int startIndex, int endIndex) { 
    if (array == null) { 
     return null; 
    } 
    if (separator == null) { 
     separator = EMPTY; 
    } 

    // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator)) 
    //   (Assuming that all Strings are roughly equally long) 
    int noOfItems = (endIndex - startIndex); 
    if (noOfItems <= 0) { 
     return EMPTY; 
    } 

    StringBuilder buf = new StringBuilder(noOfItems * 16); // THE QUESTION'S ABOUT THIS LINE 

    for (int i = startIndex; i < endIndex; i++) { 
     if (i > startIndex) { 
      buf.append(separator); 
     } 
     if (array[i] != null) { 
      buf.append(array[i]); 
     } 
    } 
    return buf.toString(); 
} 

我的問題都把StringBuilder buf = new StringBuilder(noOfItems * 16);行:

  • 我想給StringBuilder的初始容量的目標性能,因此在構建串需要較少的大小調整。我的問題是:這些調整大小的操作實際上是否會影響性能?這個策略是否真的提高了速度方面的效率? (因爲在空間方面,如果分配的空間超過必要的空間,甚至可能是負數)
  • 爲什麼使用幻數16?爲什麼他們會假設數組中的每個String長度爲16個字符?這個猜測有什麼好處?
+1

我不知道,但我猜測16是隻是平均預期大小的猜測。對於我通常需要它的用例來說,這聽起來很正確。請記住,無論如何,StringBuilder都會有一些GC'd,所以無論它是否有點太大都沒關係。保留resizings很好,因爲resizings需要複製整個前面的數組;在最壞的情況下,如果你每次調整大小,那麼你就有o(n^2)的表現。 – yshavit

回答

1

16是預期平均大小的字符串與分隔符略高估(推測是基於經驗/統計)。

預分配足夠的空間來保存整個結果避免了在執行期間用更大的(double size)數組替換後備數組並複製元素(這是O(n)操作)。

如果在大多數情況下避免替換操作,過度估計即使分配較大的陣列也是值得的。

0

真的......這不是隻有16硬編碼你說你的問題。

如果再次查看定義。你會發現這樣的事情。

bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length()) 
         + separator.length()); 
    //16 will only assigned if Object array at position StartIndex contains null. 

     StringBuffer buf = new StringBuffer(bufSize); //if null then default memory allocation for String Buffer will be 16 only. 

這裏StringBuffer將調用哪個appriviates作爲

 new StringBuffer(int Capacity); 
Constructs a string buffer with no characters in it and the specified initial capacity. 

如果對象陣列包含在索引startIndex然後默認memomy分配將是Objectlength的元件的構造。

謝謝。