編碼的發展似乎總是在簡單與複雜之間不斷徘徊,一代又一代的高手程式員們樂此不疲。當你把部分工作交給電腦時,一切都簡單了,但電腦畢竟是電腦,於是高手們漸漸提出不滿並把工作收回,接著又一批高手製造再優的程式邏輯,大家把工作還給電腦,如此往複迴圈。。。
在任意搜尋引擎找一下.NET效率最佳化就不難發現StringBuilder的身影,同時對於String的批駁也隨處可見。自從有了String這個類,“+”的操作就始終伴隨我們,如今這位戰功顯赫的朋友卻承擔著巨大的壓力,還不斷被雙規去解釋CPU和記憶體的使用問題。經過網路上的一翻調查,感覺有必要將部分真象告訴大家,故事就從這裡說起:
《Performance considerations for strings in C#》一文據說是由Dr Herbie完成,並且經過Teddy Tam的翻譯(網上太多地方轉載,就不貼連結了)。文中對StringBuilder.Append和String“+”進行瞭解釋和分析,並且給出了特定測試結果和報告。應當說真象是令人震憾的,甚至有些無奈的感覺。原來StringBuilder 通常只有在你要串連的字串數目超過 600 時才會顯示出真正的效能優勢,當然在記憶體回收的問題上還有另外的好處。雖然作者只是進行的簡單而特定的測試和分析,但也應當能夠說明一些問題。
接下來我又在網上進一步地找了找,發現StringBuilder和String的比較很多“高手”似乎有些情緒化,下面我們冷靜地談談:
1.StringBuilder本身使用時要初始化這個對象,這個可消耗不算小。
2.StringBuilder在指定容量時效果更明顯,否則它也是不斷分配記憶體。
3.String的“+”本身其實效率不算低,或者說還挺高,只是用法上導致了壞的結果。 例如
string str = "wer" + "slfls" + 。。。。。 + "lsfs";
還是相當有效得,理論上優於StringBuilder.Append。 只是因為追求代碼規範而改寫為:
string str = "wer"; str += "slfls";.......致使臨時記憶體泛濫。 4.String.Contact 和
String.Join是兩大利器。其效果同樣優於StringBuilder,至少是相差無幾。
而"+"正是得益於.NET編譯時間最佳化為String.Contact。
5.String.Contact也有軟肋,那就是支援object的參數。
程式員用的時候爽到了,但機器卻不斷調用ToString(),而對於ArrayList還得裝拆箱。
6.不論你用什麼方法,基本上已耗用時間及記憶體消耗上的差距在同一個數量級中。
即使你迴圈上百萬次也不過如此,除非你並發百萬次估計難以看到根本性變化。
有位仁兄對此做了些嘗試,也許範圍有些片面,但對於像我一樣的尋常程式員足已。
參看: http://www.cnblogs.com/xingd/archive/2005/02/06/102380.html
有時人云亦云實在是容易製造幻覺,也不知是哪位首先發起對StringBuilder的號召。甚至有人提出它就是微軟搞出來替代“+”的,這實在是說不過去。StringBuilder不止有Append一個方法,在建立一個記憶體文字資料流方面它也是相當實用的,用它來替代臨時檔案估計比耗在String問題上作用要大的多。
就我本人感覺而言,有時我們是應當忽略相當的效率的,而且也是很必要的。效率的最佳化不僅僅來自於代碼,應當說首先立足於商務邏輯,精簡的業務關係和流程是源頭;其次是從設計上考慮,基於良好的設計基礎想低效都不容易;再次是硬體和軟體平台,這上面的差距常常能莫名奇妙地省卻很多麻煩;最後才輪到代碼上,而且也應該是著眼主幹代碼,比如SQL的最佳化或緩衝使用通常更解決問題。
轉:http://blog.csdn.net/zbjg/archive/2007/03/23/1538924.aspx