在 .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 的結果,代碼如下
namespace benchmarkLab
{
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<stringBenchmark>();
Console.ReadKey();
}
}
[MemoryDiagnoser]
[ClrJob,CoreJob]
public class stringBenchmark
{
private static string firstWord = "This is a";
private static string secondWord = "book";
StringBuilder _sb = new StringBuilder();
// 測試代碼
}
}
使用 Benchmark 測試數據,需要在方法上加上 Benchmark attribute,使用 string 的相加測試的代碼如下[Benchmark]
public void Normal()
{
string s = string.Empty;
s = firstWord;
s += secondWord;
}
使用 stringBuilder 的相加測試的代碼如下
另外一種使用 stringBuilder 的方式,將其宣告為區域變數使用前先 clear,測試的代碼如下
測試完成後,會產生測試報各路徑在 release\BenchmarkDotNet.Artifacts\results 目錄底下,如下圖所示
根據測試結果
.NET Framework : 表現最差的為 string.Format,表現最好的是 string 相加
.NET Core : 表現最差的為 string.Format,表現最好的是 Interpolation
[Benchmark]
public void StringBuilder()
{
StringBuilder sb = new StringBuilder();
sb.Append(firstWord);
sb.Append(secondWord);
string s = sb.ToString();
}
[Benchmark]
public void StringBuilderClear()
{
_sb.Clear();
_sb.Append(firstWord);
_sb.Append(secondWord);
string s = _sb.ToString();
}
使用 string.Format,測試的代碼如下[Benchmark]
public void Format()
{
string s = string.Empty;
s = string.Format("{0} {1}", firstWord, secondWord);
}
使用 C# 6.0 提供的新語法 Interpolation,測試的代碼如下[Benchmark]
public void Interpolation()
{
string s = string.Empty;
s = $"{firstWord}{secondWord}";
}
使用 string.Concat,測試的代碼如下[Benchmark]
public void Concat()
{
string s = string.Empty;
s = string.Concat(firstWord, secondWord);
}
使用 string.Join,測試的代碼如下[Benchmark]
public void Join()
{
string s = firstWord;
s += string.Join(s, secondWord);
}
接著調整到 Release mode,按下 F5 進行測試測試完成後,會產生測試報各路徑在 release\BenchmarkDotNet.Artifacts\results 目錄底下,如下圖所示
根據測試結果
感想
參考
在 ASP.NET Core 中使用多個環境



0 意見:
張貼留言