2011-07-29 160 views
5

所以我主要是一個C#和Java開發人員,但我想這個問題可能與任何使用StringBuilder或其衍生物的編程語言有關。對一個字符串使用多個字符串構建器

好的,即使連接少量字符串也可能成爲一個主要的性能殺手(儘管這是有爭議的),或多或少都是常識。我的問題是沒有人知道在字符串生成器中使用字符串生成器的性能效果。爲了澄清我的意思,讓我加入一些虛擬代碼,以幫助說明我的觀點。

另外我意識到,通過調用StringBuilder的多個實例,性能自然會受到影響,但我不相信我會調用它足以導致任何實際性能問題。 (這個假設也可能是錯誤的,任何意見將是有益的爲好)

public string StringToGet() 
{ 
    StringBuilder sb = new StringBuilder("Some Text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append(MethodThatCreatesAnotherString()); 
    //etc 

    return sb.toString(); 

} 

private string MethodThatCreatesAnotherString() 
{ 
    StringBuilder sb = new StringBuilder("Other text"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 

    return sb.ToString(); 
} 

邏輯告訴我,這不應該是一個問題,但只是似乎一些關於這種做法不正確的看我。任何人都可以擺脫對下列問題的一些輕

  1. 這是否創建一個顯著更大的性能損失的不僅僅是不使用額外的方法和使用單一的StringBuilder
  2. 是在一個合理的可以接受的做法。

任何現場就此將不勝感激。

+0

這個問題比得到的值得多。這種算法肯定有應用。 – Panzercrisis

回答

9

通常情況下,如果直接字符串連接的數量超過5個,最好使用StringBuilder。如果您可以控制依次構建字符串的方法,爲什麼不考慮將StringBuilder傳入方法?

public void MethodThatCreatesAnotherString(StringBuilder sb) 
{ 
    // code that appends to StringBuilder 
} 

所以,當它的時間來調用該函數,你在當前StringBuilder通了,你不輸性能損失,但它是在潛在的混淆爲代價的。

這就是說,除非你進入成百上千的這些操作,否則我不會擔心這裏的過早優化。你的主要性能是兩次(即追加方法內的字符串,然後追加完整的字符串),但你仍然不會在使用連接的程度上達到性能。

編輯:如何使用它闡明的例子:

string SomeMethodCreatingAString() 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    sb.append("more text to add"); 
    MethodThatCreatesAnotherString(sb); 
    // more text 
    return sb.ToString(); 
} 

所以,你永遠不要追加從第二個方法是字符串,您只需使用相同的StringBuilder該方法中。希望這是有道理的。

+0

這是一個非常好的點drharris和@Scott Munro,我有些尷尬地說我沒有考慮。這聽起來像是在這種方法下,原始字符串生成器只是將Append(SomeMethod())視爲另一個字符串,它基本上會回答我的問題。 – pat8719

+0

我意識到我沒有給出如何調用它的實際說明。希望你能理解這個意圖,但是如果有其他人出現,我加了一個例子。不要擔心不考慮它;這是一個像其他一切的設計決定,並不總是最好的辦法。通過返回'void',這個方法隱藏了它真正的作用,這有時不是最好的方法。有時候,您寧願花費額外的毫秒來獲得更清晰的代碼。 – drharris

+0

我明白你的意圖,但無論如何謝謝你。基於所有這些答案的一般觀點,我認爲,爲了清晰的代碼,我最好避免方法中的「空白」返回,特別是考慮到性能命中可能非常小的事實。 。 – pat8719

4

我不知道的性能影響,但改變你MethodThatCreatesAnotherString方法的簽名接受StringBuilder將消除需要的StringBuilder多個實例。

4

由於http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html顯示連接字符串的不同方式之間的差異真的非常小,直到你真的很大數量的連接。

因此,除非你已經知道你有這個代碼的性能問題,那麼我認爲它很好。你真的只在你的例子中獲得3個額外的字符串生成器inits和3個額外的字符串分配。

從長遠來看,您應該嘗試做最簡單的事情,只需要擔心複雜的微觀優化問題,如果您確定需要它們並進行測試即可。

+0

+1這確實是一個公平點,但是因爲我確實傾向於本能地使用StringBuilder,所以我的問題確實旨在確保使用所謂的「嵌入式」StringBuilders時不存在任何錯誤。感謝您分享這篇文章。 – pat8719