C#中字符串拼接方式及其性能分析對比
前言
在C#編程中字符串拼接是一種常見且基礎(chǔ)的操作,廣泛應(yīng)用于各種場景,如動態(tài)生成SQL查詢、構(gòu)建日志信息、格式化用戶顯示內(nèi)容等。然而,不同的字符串拼接方式在性能和內(nèi)存使用上可能存在顯著差異。今天咱們一起來看看在C#中字符串拼接的常見6種方式及其使用BenchmarkDotNet
進(jìn)行性能分析對比。
BenchmarkDotNet
BenchmarkDotNet是一個(gè)基于.NET開源、功能全面、易于使用的性能基準(zhǔn)測試框架,它為.NET開發(fā)者提供了強(qiáng)大的性能評估和優(yōu)化能力。通過自動化測試、多平臺支持、高級統(tǒng)計(jì)分析和自定義配置等特性,BenchmarkDotNet幫助開發(fā)者更好地理解和優(yōu)化軟件系統(tǒng)的性能表現(xiàn)。
使用教程詳細(xì)介紹:使用BenchmarkDotNet對.NET代碼進(jìn)行性能基準(zhǔn)測試
拼接基礎(chǔ)數(shù)據(jù)
private const int IterationCount = 1000; private const string StringPart1 = "追逐時(shí)光者"; private const string StringPart2 = "DotNetGuide"; private const string StringPart3 = "DotNetGuide技術(shù)社區(qū)"; private readonly string[] _stringPartsArray = { "追逐時(shí)光者", "DotNetGuide", "DotNetGuide技術(shù)社區(qū)" };
+操作符
/// <summary> /// 使用 + 操作符拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string PlusOperator() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += StringPart1 + " " + StringPart2 + " " + StringPart3; } return result; }
$內(nèi)插字符串
/// <summary> /// 使用 $ 內(nèi)插字符串拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string InterpolatedString() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += $"{StringPart1} {StringPart2} {StringPart3}"; } return result; }
String.Format
/// <summary> /// 使用string.Format()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringFormat() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Format("{0} {1} {2}", StringPart1, StringPart2, StringPart3); } return result; }
String.Concat
/// <summary> /// 使用string.Concat()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringConcat() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Concat(StringPart1, " ", StringPart2, " ", StringPart3); } return result; }
String.Join
/// <summary> /// 使用string.Join()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringJoin() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Join(" ", _stringPartsArray); } return result; }
StringBuilder
/// <summary> /// 使用StringBuilder拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringBuilder() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < IterationCount; i++) { stringBuilder.Append(StringPart1); stringBuilder.Append(" "); stringBuilder.Append(StringPart2); stringBuilder.Append(" "); stringBuilder.Append(StringPart3); } return stringBuilder.ToString(); }
性能基準(zhǔn)對比測試完整代碼
[MemoryDiagnoser]//記錄內(nèi)存分配情況 public class StringConcatenationBenchmark { private const int IterationCount = 1000; private const string StringPart1 = "追逐時(shí)光者"; private const string StringPart2 = "DotNetGuide"; private const string StringPart3 = "DotNetGuide技術(shù)社區(qū)"; private readonly string[] _stringPartsArray = { "追逐時(shí)光者", "DotNetGuide", "DotNetGuide技術(shù)社區(qū)" }; /// <summary> /// 使用 + 操作符拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string PlusOperator() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += StringPart1 + " " + StringPart2 + " " + StringPart3; } return result; } /// <summary> /// 使用 $ 內(nèi)插字符串拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string InterpolatedString() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += $"{StringPart1} {StringPart2} {StringPart3}"; } return result; } /// <summary> /// 使用string.Format()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringFormat() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Format("{0} {1} {2}", StringPart1, StringPart2, StringPart3); } return result; } /// <summary> /// 使用string.Concat()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringConcat() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Concat(StringPart1, " ", StringPart2, " ", StringPart3); } return result; } /// <summary> /// 使用string.Join()拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringJoin() { string result = string.Empty; for (int i = 0; i < IterationCount; i++) { result += string.Join(" ", _stringPartsArray); } return result; } /// <summary> /// 使用StringBuilder拼接字符串 /// </summary> /// <returns></returns> [Benchmark] public string StringBuilder() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < IterationCount; i++) { stringBuilder.Append(StringPart1); stringBuilder.Append(" "); stringBuilder.Append(StringPart2); stringBuilder.Append(" "); stringBuilder.Append(StringPart3); } return stringBuilder.ToString(); } }
性能基準(zhǔn)對比測試分析報(bào)告
Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
---|---|---|---|---|---|---|
PlusOperator | 2,066.28 us | 35.761 us | 63.566 us | 5238.2813 | 789.0625 | 32283.12 KB |
InterpolatedString | 1,984.56 us | 29.949 us | 28.014 us | 5238.2813 | 789.0625 | 32283.12 KB |
StringFormat | 2,112.02 us | 25.020 us | 23.404 us | 5257.8125 | 777.3438 | 32369.06 KB |
StringConcat | 2,027.09 us | 28.300 us | 26.472 us | 5257.8125 | 777.3438 | 32369.06 KB |
StringJoin | 2,017.36 us | 27.111 us | 22.639 us | 5257.8125 | 777.3438 | 32369.06 KB |
StringBuilder | 13.63 us | 0.065 us | 0.058 us | 23.2544 | 4.6387 | 143.96 KB |
說明:
- Mean: 所有測量值的算術(shù)平均值。
- Error: 99.9% 置信區(qū)間的一半。
- StdDev: 所有測量值的標(biāo)準(zhǔn)差。
- Gen0: 第 0 代 GC 每 1000 次操作收集一次。
- Gen1: 第 1 代 GC 每 1000 次操作收集一次。
- Gen2: 第 2 代 GC 每 1000 次操作收集一次。
- Allocated: 每次操作分配的內(nèi)存(僅托管內(nèi)存,包含所有內(nèi)容,1KB = 1024B)。
- 1 ms: 1 毫秒(0.001 秒)。
性能基準(zhǔn)對比測試結(jié)論
從上面的性能基準(zhǔn)對比測試分析報(bào)告來看StringBuilder
是性能最好的字符串拼接方式,特別是在需要頻繁進(jìn)行拼接的場景中。其他方式(如+操作符
、$內(nèi)插字符串
、String.Format
、String.Concat
和String.Join
)在性能上相對較差,因?yàn)樗鼈儠?dǎo)致多次內(nèi)存分配和復(fù)制。
因此我們在選擇字符串拼接方式時(shí),應(yīng)該根據(jù)具體場景和需求進(jìn)行選擇。如果性能是關(guān)鍵因素,并且需要頻繁進(jìn)行拼接,則應(yīng)使用StringBuilder
。如果代碼簡潔性和易讀性更重要,并且拼接次數(shù)較少,則可以考慮使用其他方式。
以上就是C#中字符串拼接方式及其性能分析對比的詳細(xì)內(nèi)容,更多關(guān)于C#字符串拼接的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MessageBox的Buttons和三級聯(lián)動效果
這篇文章主要介紹了MessageBox的Buttons和三級聯(lián)動的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11C#程序調(diào)用C++動態(tài)庫(dll文件)遇到的坑及解決
這篇文章主要介紹了C#程序調(diào)用C++動態(tài)庫(dll文件)遇到的坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08C# WinForm實(shí)現(xiàn)自動更新程序之客戶端的示例代碼
這篇文章主要為大家詳細(xì)介紹了利用C# WinForm實(shí)現(xiàn)自動更新程序之客戶端的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-10-10C#實(shí)現(xiàn)數(shù)據(jù)去重的方式總結(jié)
這篇文章主要來和大家一起來討論一下關(guān)于C#數(shù)據(jù)去重的常見的幾種方式,每種方法都有其特點(diǎn)和適用場景,感興趣的小伙伴可以了解一下2023-07-07