改進(jìn)C#連接字符串的性能
.NET 框架中的C#連接字符串描述
比 Visual C/C++ 中的 strcat() 更好的C#連接字符串的一項(xiàng)技術(shù)是,分配一個(gè)大字符數(shù)組作為緩沖區(qū),并將字符串?dāng)?shù)據(jù)復(fù)制到緩沖區(qū)中。 在 .NET 框架中,字符串是不變的;不能就地對(duì)字符串進(jìn)行修改。 C# + 連接運(yùn)算符生成一個(gè)新的字符串,在連接大量文本時(shí)會(huì)造成性能下降。
但是,.NET 框架包含一個(gè) StringBuilder 類(lèi),它已經(jīng)專(zhuān)門(mén)為字符串連接進(jìn)行了優(yōu)化。 該類(lèi)與 C/C++ 中使用的字符串?dāng)?shù)組有同樣的好處,并且還能(根據(jù)需要)自動(dòng)增大緩沖區(qū)大小并跟蹤長(zhǎng)度。本文中的示例應(yīng)用程序演示了 StringBuilder 類(lèi)的使用并將其性能與字符串連接技術(shù)進(jìn)行比較。
生成和運(yùn)行演示應(yīng)用程序
啟動(dòng) Visual Studio .NET 并新建一個(gè) Visual C# 控制臺(tái)應(yīng)用程序。
以下代碼使用 += 連接運(yùn)算符和 StringBuilder 類(lèi),分別對(duì)每次 30 個(gè)字符,共 5,000 次連接進(jìn)行計(jì)時(shí)。 將此代碼添加到 Main 過(guò)程中。
- const int sLen=30, Loops=5000;
- DateTime sTime, eTime;
- int i;
- string sSource = new String('X', sLen);
- string sDest = "";
- //
- // Time string concatenation.
- //
- sTime = DateTime.Now;
- for(i=0;ieTime = DateTime.Now;
- Console.WriteLine("Concatenation took " + (eTime - sTime).TotalSeconds + " seconds.");
- //
- // Time StringBuilder.
- //
- sTime = DateTime.Now;
- System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
- for(i=0;isDest = sb.ToString();
- eTime = DateTime.Now;
- Console.WriteLine("String Builder took " + (eTime - sTime).TotalSeconds + " seconds.");
- //
- // Make the console window stay open
- // so that you can see the results when running from the IDE.
- //
- Console.WriteLine();
- Console.Write("Press Enter to finish ... ");
- Console.Read();
保存應(yīng)用程序,按 F5 鍵編譯并運(yùn)行該應(yīng)用程序。控制臺(tái)窗口應(yīng)輸出類(lèi)似下面的顯示:
Concatenation took 6.208928 seconds.
String Builder took 0 seconds.
Press ENTER to finish ...
按 ENTER 鍵停止運(yùn)行應(yīng)用程序并關(guān)閉控制臺(tái)窗口。
C#連接字符串疑難解答
如果您是在支持?jǐn)?shù)據(jù)流式處理的環(huán)境(如 ASPX Web 窗體)中,或者您的應(yīng)用程序能將數(shù)據(jù)寫(xiě)入磁盤(pán),則請(qǐng)考慮避免字符串連接或 StringBuilder 的緩沖負(fù)擔(dān),而使用 Response.Write 方法或適合數(shù)據(jù)流的適當(dāng)方法將數(shù)據(jù)直接寫(xiě)入數(shù)據(jù)流。
請(qǐng)盡量再次使用現(xiàn)有的 StringBuilder 類(lèi),而不要在每次需要時(shí)都重新分配。這樣可限制堆的增長(zhǎng)并減少垃圾集合。 在這兩種情況下,與使用 + 運(yùn)算符相比,使用 StringBuilder 類(lèi)可以更有效地使用堆。
【編輯推薦】