C#字符串拼接的几种方式及其性能分析对比

前言

在C#编程中字符串拼接是一种常见且基础的操作,广泛应用于各种场景,如动态生成SQL查询、构建日志信息、格式化用户显示内容等。然而,不同的字符串拼接方式在性能和内存使用上可能存在显著差异。今天咱们一起来看看在C#中字符串拼接的常见6种方式及其使用BenchmarkDotNet进行性能分析对比。

BenchmarkDotNet

BenchmarkDotNet是一个基于.NET开源、功能全面、易于使用的性能基准测试框架,它为.NET开发者提供了强大的性能评估和优化能力。通过自动化测试、多平台支持、高级统计分析和自定义配置等特性,BenchmarkDotNet帮助开发者更好地理解和优化软件系统的性能表现。

拼接基础数据


ini

代码解读

复制代码

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技术社区" };

+操作符


csharp

代码解读

复制代码

        /// <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;         }

$内插字符串


csharp

代码解读

复制代码

        /// <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


csharp

代码解读

复制代码

        /// <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


csharp

代码解读

复制代码

        /// <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


csharp

代码解读

复制代码

        /// <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


csharp

代码解读

复制代码

        /// <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();         }

性能基准对比测试完整代码


csharp

代码解读

复制代码

    [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();         }     }

性能基准对比测试分析报告

MethodMeanErrorStdDevGen0Gen1Allocated
PlusOperator2,066.28 us35.761 us63.566 us5238.2813789.062532283.12 KB
InterpolatedString1,984.56 us29.949 us28.014 us5238.2813789.062532283.12 KB
StringFormat2,112.02 us25.020 us23.404 us5257.8125777.343832369.06 KB
StringConcat2,027.09 us28.300 us26.472 us5257.8125777.343832369.06 KB
StringJoin2,017.36 us27.111 us22.639 us5257.8125777.343832369.06 KB
StringBuilder13.63 us0.065 us0.058 us23.25444.6387143.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.FormatString.ConcatString.Join)在性能上相对较差,因为它们会导致多次内存分配和复制。

因此我们在选择字符串拼接方式时,应该根据具体场景和需求进行选择。如果性能是关键因素,并且需要频繁进行拼接,则应使用StringBuilder。如果代码简洁性和易读性更重要,并且拼接次数较少,则可以考虑使用其他方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值