只有累積,沒有奇蹟

2022年11月7日 星期一

[NETCore] String 字串相加效能比較

前言
在 .NET 應用程式中很常使用到 string 型別,string 是不可變 ( Immutable ) 的,當每次建立完就會固定其長度,如果要做相加就必須捨棄原有使用的記憶體,在重新配置一塊新的記憶體給它使用,如果在需要大量得字串動態相加時就會影響到其效能,因此在動態文字相加情境就可以透過 stringBuilder 來改善此問題,詳細細節可以參考黑暗大的 StringBuilder串接字串的迷思,這篇重點是在 C# 有提供多種語法來做 string 相加語法,像是 string.Format、stringBuilder、Concat、Join 以及 Interpolation 多種方法,今天就要針對 C# 中提供的字串相加效能進行比較,以及測試的結果數據,若有問題或是錯誤的地方歡迎各位給予指導及討論

測試代碼 
測試方式以  BenchmarkDotNet  套件協助進行測試,BenchmarkDotNet 可以針對要測試的方法紀錄執行時間,並會將測試結果輸出報告,如果對此套件有興趣可以參考介紹的文章 [.NETCore] 使用 BenchmarkDotNet 測試程式碼效能首先先針對固定字串相加做測試,定義區域變數 firstWord 與 secondWord 希望輸出 This is a book 字眼,另外在 stringBenchmark 類別加上  ClrJob,CoreJob  希望分別在 .NET Framework 與 .NET Core 測試效能差異,加上  MemoryDiagnoser  輸出測試時觀察 GC 的結果,代碼如下 
  1. namespace benchmarkLab
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. var summary = BenchmarkRunner.Run<stringBenchmark>();
  8. Console.ReadKey();
  9. }
  10. }
  11.  
  12. [MemoryDiagnoser]
  13. [ClrJob,CoreJob]
  14. public class stringBenchmark
  15. {
  16. private static string firstWord = "This is a";
  17. private static string secondWord = "book";
  18. StringBuilder _sb = new StringBuilder();
  19.  
  20. // 測試代碼
  21. }
  22. }
使用 Benchmark 測試數據,需要在方法上加上 Benchmark  attribute,使用 string 的相加測試的代碼如下
  1. [Benchmark]
  2. public void Normal()
  3. {
  4. string s = string.Empty;
  5. s = firstWord;
  6. s += secondWord;
  7. }
使用 stringBuilder 的相加測試的代碼如下
  1. [Benchmark]
  2. public void StringBuilder()
  3. {
  4. StringBuilder sb = new StringBuilder();
  5. sb.Append(firstWord);
  6. sb.Append(secondWord);
  7. string s = sb.ToString();
  8. }
另外一種使用 stringBuilder 的方式,將其宣告為區域變數使用前先 clear,測試的代碼如下
  1. [Benchmark]
  2. public void StringBuilderClear()
  3. {
  4. _sb.Clear();
  5. _sb.Append(firstWord);
  6. _sb.Append(secondWord);
  7. string s = _sb.ToString();
  8. }
使用 string.Format,測試的代碼如下
  1. [Benchmark]
  2. public void Format()
  3. {
  4. string s = string.Empty;
  5. s = string.Format("{0} {1}", firstWord, secondWord);
  6. }
使用 C# 6.0 提供的新語法 Interpolation,測試的代碼如下
  1. [Benchmark]
  2. public void Interpolation()
  3. {
  4. string s = string.Empty;
  5. s = $"{firstWord}{secondWord}";
  6. }
使用 string.Concat,測試的代碼如下
  1. [Benchmark]
  2. public void Concat()
  3. {
  4. string s = string.Empty;
  5. s = string.Concat(firstWord, secondWord);
  6. }
使用 string.Join,測試的代碼如下
  1. [Benchmark]
  2. public void Join()
  3. {
  4. string s = firstWord;
  5. s += string.Join(s, secondWord);
  6. }
接著調整到 Release mode,按下 F5 進行測試
測試完成後,會產生測試報各路徑在  release\BenchmarkDotNet.Artifacts\results  目錄底下,如下圖所示
根據測試結果


  • .NET Framework : 表現最差的為 string.Format,表現最好的是 string 相加
  • .NET Core : 表現最差的為 string.Format,表現最好的是 Interpolation

  • 感想
    透過結果得知,在 .NET Framework 與 .NET Core 環境中在 靜態字串 相加的情況下,string 相加效能會比使用 stringBuilder 來的好 (原因可以參考黑暗大文章 StringBuilder串接字串的迷思,這裡就不在細說),Interpolation 與 conact 落後一些也是表現不錯,唯有 string.Format 在兩個皆墊底,.NET Framework 最好與最差的差距近 6 倍 ( 31.9 v.s 238.0 ),在 .NET Core 更高達 9 倍 (38.2 v.s 312.2 ),如果有需要用到時需要特別留意,避免影響到網站執行效能,下次再來分享動態文字的測試數據 (拖稿),Happy Coding :)

    參考
    在 ASP.NET Core 中使用多個環境

    Related Posts:

    • [C#] 如何建立XML CDATA元素 摘要:C#如何建立XML CDATA元素 在與其他產品或服務Web services做溝通時,常常都會使用XML做資料交換的格式 最近遇到一個很特殊的案例,對方希望在傳過去的XML內容包兩層,第二層外面Tag要加上<![CDATA[" XML內容 "]]> XML文字內容只要被<![CDATA[和]]>包在裡面的,XML解析器在解析時就不會去解析裡面的內容,這樣的文字稱為Character Data … Read More
    • [IIS] 如何在 Windows 10 Pro 安裝 IIS 前言 最近有幸拿到公司配的新筆電,發現筆電上除了Visual Studio與SQL Server其他常用的都未安裝 難得有重新IIS站台的機會,雖然不難但最近初老症狀有點嚴重(?,這裡簡單紀錄一下IIS安裝過程 安裝過程 Control > Programs > Turn Windows features on or off Internet Information Services 項目打勾 展開 Internet Inform… Read More
    • [.NET] ASP.NET 網頁生命週期 Page Life-Cycle 使用者透過瀏覽器發送一個請求(Request)到伺服器端,伺服器端會依照請求內容讀取所需要的資料,並建立ASP.NET Page物件,當執行 ASP.NET 網頁時,網頁在生命週期內會執行一系列處理步驟。其中包括初始化、產生控制項、還原和維護狀態、執行事件處理常式程式碼和呈現(參考MSDN網站)。伺服器端將結果組成網頁程式碼(HTML)供瀏覽器讀取及呈現,回傳結果分為兩個部分,第一部分為網頁的呈現資料(HTML Tag)、第二部份為(hidd… Read More
    • [C#] string.Format 格式整理 [筆記] string.Format輸出格式懶人包 紀錄以下幾種用法,並紀錄輸出格式 1. 標準數值格式 2. 自訂數值格式 3. 標準DateTime格式 4. 自訂DateTime格式 5. 字串格式 前言 常用到string.Format方法,每次用到都要上網查說明,心想不如整理成文章懶人包方便自己日後查詢,若有錯誤的地方,請各位不吝指教 標準數值格式 格式 說明 Format Input Output 補充 … Read More
    • [HTTP] HTTP GET、POST Method HTTP     Http(Hypertext Transfer Protocol)是一種通訊協定,用於網頁發出請求(Request)給伺服器,伺服器將要Render的資料回傳(Response)給網頁瀏覽器使用,Http訊息通常是透過80 port或是443 port(Secure http)往返網頁瀏覽器與伺服器之間。     使用者在瀏覽器網址輸入URL(Unifo… Read More

    0 意見:

    張貼留言

    Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com