C#中字符串拼接方式及其性能分析对比
作者:追逐时光者
在C#编程中字符串拼接是一种常见且基础的操作,广泛应用于各种场景,如动态生成SQL查询,构建日志信息等,本文为大家整理了C#中字符串拼接的常见6种方式及其使用BenchmarkDotNet进行性能分析对比,需要的可以参考下
前言
在C#编程中字符串拼接是一种常见且基础的操作,广泛应用于各种场景,如动态生成SQL查询、构建日志信息、格式化用户显示内容等。然而,不同的字符串拼接方式在性能和内存使用上可能存在显著差异。今天咱们一起来看看在C#中字符串拼接的常见6种方式及其使用BenchmarkDotNet
进行性能分析对比。
BenchmarkDotNet
BenchmarkDotNet是一个基于.NET开源、功能全面、易于使用的性能基准测试框架,它为.NET开发者提供了强大的性能评估和优化能力。通过自动化测试、多平台支持、高级统计分析和自定义配置等特性,BenchmarkDotNet帮助开发者更好地理解和优化软件系统的性能表现。
使用教程详细介绍:使用BenchmarkDotNet对.NET代码进行性能基准测试
拼接基础数据
private const int IterationCount = 1000; private const string StringPart1 = "追逐时光者"; private const string StringPart2 = "DotNetGuide"; private const string StringPart3 = "DotNetGuide技术社区"; private readonly string[] _stringPartsArray = { "追逐时光者", "DotNetGuide", "DotNetGuide技术社区" };
+操作符
/// <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> /// 使用 $ 内插字符串拼接字符串 /// </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(); }
性能基准对比测试完整代码
[MemoryDiagnoser]//记录内存分配情况 public class StringConcatenationBenchmark { private const int IterationCount = 1000; private const string StringPart1 = "追逐时光者"; private const string StringPart2 = "DotNetGuide"; private const string StringPart3 = "DotNetGuide技术社区"; private readonly string[] _stringPartsArray = { "追逐时光者", "DotNetGuide", "DotNetGuide技术社区" }; /// <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> /// 使用 $ 内插字符串拼接字符串 /// </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(); } }
性能基准对比测试分析报告
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: 所有测量值的算术平均值。
- Error: 99.9% 置信区间的一半。
- StdDev: 所有测量值的标准差。
- Gen0: 第 0 代 GC 每 1000 次操作收集一次。
- Gen1: 第 1 代 GC 每 1000 次操作收集一次。
- Gen2: 第 2 代 GC 每 1000 次操作收集一次。
- Allocated: 每次操作分配的内存(仅托管内存,包含所有内容,1KB = 1024B)。
- 1 ms: 1 毫秒(0.001 秒)。
性能基准对比测试结论
从上面的性能基准对比测试分析报告来看StringBuilder
是性能最好的字符串拼接方式,特别是在需要频繁进行拼接的场景中。其他方式(如+操作符
、$内插字符串
、String.Format
、String.Concat
和String.Join
)在性能上相对较差,因为它们会导致多次内存分配和复制。
因此我们在选择字符串拼接方式时,应该根据具体场景和需求进行选择。如果性能是关键因素,并且需要频繁进行拼接,则应使用StringBuilder
。如果代码简洁性和易读性更重要,并且拼接次数较少,则可以考虑使用其他方式。
以上就是C#中字符串拼接方式及其性能分析对比的详细内容,更多关于C#字符串拼接的资料请关注脚本之家其它相关文章!