前一陣子在 Review Vendor 交過來的 Source code 的時候,發現裡頭用了大量的 StringBuilder 與 .Append 的 Method,其實我自己本身在寫 .NET 程式的時候,很少會去用到這些 Framework 所提供的功能,字串的結合都是用 s += “something else.”; 的方式解決掉的。最近因為該系統執行的效能不彰,所以對這一些 Source code 又重新 review 一次,並且作了一些效能上的調校,比如說: 把用了大量 DataSet 的程式碼 (一個 DataSet 只包了一個 DataTable),改成一個 DataSet 包了多個 DataTable 來運行,並且將一些 SQL 指令放進 Stored Procedure 去跑,希望這樣能夠增加一些效率,減少 DB Lock 產生的系統延遲等等 (日後有空再來寫一篇)。
剛剛提到在這些程式碼中,用了大量的 StringBuilder.Append,我對於這個東西的效能存疑,於是上網找了一下資料,先是 Google 了這一篇:
http://www.c-sharpcorner.com/Code/2002/Oct/StringBuilderComp.asp
Mahesh Chand 用了簡單的迴圈模擬出使用 StringBuilder 與 += Operator 的差異,很明顯的發現了 StringBuilder 的速度比 += 快得多了,似乎我們的這個 Vendor 也懂得這個道理,於是所有的字串組合都用了 StringBuilder 來作,這種寫法還得多敲些鍵,所以不算是偷懶了。等等,i<10000 這一行有點懸機,要一萬行的字串組合才有效能的提升,那 StringBuilder 難道不需要建構嗎?建構也是需要花時間的吧!我們常會寫 StringBuilder sb = new StringBuilder(); 這一行程式會用在需要用 StringBuilder 之前,而且常常不會用它來作很多 Append 就把它給 Dispose 掉了,我手上看到的 Source code 也多是 Append 個七至八次就結束,那麼上述文章的論點就值得再深入研究了,再拜 Google 大神給更多明確的指示,出籤:
http://www.heikniemi.net/hc/archives/000124.html
Jouni Heikniemi 的這一篇顯然比較科學,他點出的疑點與我相同,而且使用了更科學的方法來測試兩種寫法的效能,並找出最佳的 Magic Number,這當然要把 StringBuilder 建構時間也考慮進去,依此數據,如果你的 Append 小於 8 次的話,就只用 += 就行了,還能減少輸入程式時的敲鍵數。
字串長度也是一個影響此測試的因素,但在我的情況下,多數 SQL 指令的長度都不會超過 1024 Bytes… So?
[續]——————}
於是決定以後在看到 source code 中有 StringBuder.Append 都不作修改,而自己寫的程式,需要用到 Append 方式處理字串時則依據小於 8 使用 += 大於等於 8 使用 StringBuilder 的原則處理,但是在寫底層 Class 時,由於不能假設使用 Class 的人不會用長字串,則盡量使用 StringBuilder 來處理。