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

前言

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

BenchmarkDotNet

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

拼接基础数据

复制代码
`        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 = StringPart1 + " " + StringPart2 + " " + StringPart3;`
`            return result;`
`        }`

$内插字符串

复制代码
`        /// <summary>`
`        /// 使用 $ 内插字符串拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string InterpolatedString()`
`        {`
`            string result = $"{StringPart1} {StringPart2} {StringPart3}";`
`            return result;`
`        }`

String.Format

复制代码
`        /// <summary>`
`        /// 使用string.Format()拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringFormat()`
`        {`
`            string 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.Concat(StringPart1, " ", StringPart2, " ", StringPart3);`
`            return result;`
`        }`

String.Join

复制代码
`        /// <summary>`
`        /// 使用string.Join()拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringJoin()`
`        {`
`            string result = string.Join(" ", _stringPartsArray);`
`            return result;`
`        }`

StringBuilder

Append拼接字符串

复制代码
`        /// <summary>`
`        /// 使用StringBuilder.Append拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringBuilderAppend()`
`        {`
`            StringBuilder stringBuilder = new StringBuilder();`
`            stringBuilder.Append(StringPart1);`
`            stringBuilder.Append(" ");`
`            stringBuilder.Append(StringPart2);`
`            stringBuilder.Append(" ");`
`            stringBuilder.Append(StringPart3);`
`            return stringBuilder.ToString();`
`        }`

AppendFormat拼接字符串

复制代码
`        /// <summary>`
`        /// 使用StringBuilder.AppendFormat拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringBuilderAppendFormat()`
`        {`
`            StringBuilder stringBuilder = new StringBuilder();`
`            stringBuilder.AppendFormat("{0} {1} {2}", StringPart1, StringPart2, StringPart3);`
`            return stringBuilder.ToString();`
`        }`

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

咱们分别以少量字符串拼接和大量字符串拼接为例,进行性能基准对比测试:

说明:

  • 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 秒)。

少量字符串拼接

复制代码
`   using BenchmarkDotNet.Attributes;`
`using System.Text;`

`namespace BenchmarkDotNetExercise`
`{`
`    [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技术社区" };`

`        #region 少量字符串拼接`

`        /// <summary>`
`        /// 使用 + 操作符拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string PlusOperator()`
`        {`
`            string result = StringPart1 + " " + StringPart2 + " " + StringPart3;`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用 $ 内插字符串拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string InterpolatedString()`
`        {`
`            string result = $"{StringPart1} {StringPart2} {StringPart3}";`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用string.Format()拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringFormat()`
`        {`
`            string result = string.Format("{0} {1} {2}", StringPart1, StringPart2, StringPart3);`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用string.Concat()拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringConcat()`
`        {`
`            string result = string.Concat(StringPart1, " ", StringPart2, " ", StringPart3);`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用string.Join()拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringJoin()`
`        {`
`            string result = string.Join(" ", _stringPartsArray);`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用StringBuilder.Append拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringBuilderAppend()`
`        {`
`            StringBuilder stringBuilder = new StringBuilder();`
`            stringBuilder.Append(StringPart1);`
`            stringBuilder.Append(" ");`
`            stringBuilder.Append(StringPart2);`
`            stringBuilder.Append(" ");`
`            stringBuilder.Append(StringPart3);`
`            return stringBuilder.ToString();`
`        }`

`        /// <summary>`
`        /// 使用StringBuilder.AppendFormat拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string StringBuilderAppendFormat()`
`        {`
`            StringBuilder stringBuilder = new StringBuilder();`
`            stringBuilder.AppendFormat("{0} {1} {2}", StringPart1, StringPart2, StringPart3);`
`            return stringBuilder.ToString();`
`        }`

`        #endregion`
`    }`
`}`

大量字符串拼接

复制代码
`   using BenchmarkDotNet.Attributes;`
`using System.Text;`

`namespace BenchmarkDotNetExercise`
`{`
`    [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技术社区" };`

`        #region 大量字符串拼接`

`        /// <summary>`
`        /// 使用 + 操作符拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string BigDataPlusOperator()`
`        {`
`            string result = string.Empty;`
`            for (int i = 0; i < IterationCount; i++)`
`            {`
`                result += StringPart1 + " " + StringPart2 + " " + StringPart3;`
`            }`
`            return result;`
`        }`

`        /// <summary>`
`        /// 使用StringBuilder.Append拼接字符串`
`        /// </summary>`
`        /// <returns></returns>`
`        [Benchmark]`
`        public string BigDataStringBuilderAppend()`
`        {`
`            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();`
`        }`

`        #endregion`
`    }`
`}`
相关推荐
追逐时光者1 天前
C#/.NET/.NET Core技术前沿周刊 | 第 24 期(2025年1.27-1.31)
【.net】·【c#】·【开源项目】·【.net core】·【技术前沿周刊】
追逐时光者2 天前
C#/.NET/.NET Core技术前沿周刊 | 第 25 期(2025年2.1-2.9)
【.net】·【c#】·【.net core】·【技术前沿周刊】
追逐时光者3 天前
C#/.NET/.NET Core优秀项目和框架2025年1月简报
【.net】·【c#】·【开源项目】·【.net core】·【每月简报】
追逐时光者5 天前
2025年值得推荐的 8 款 WPF UI 控件库
【.net】·【c#】·【开源项目】·【.net core】·【wpf】
追逐时光者6 天前
一款基于 WPF 开源、功能全面的串口调试工具
【.net】·【c#】·【开源项目】·【wpf】
追逐时光者7 天前
一个基于 C# 开源的第三方 OAuth2 授权登录整合库
【.net】·【c#】·【开源项目】
追逐时光者8 天前
一款由 .NET 官方团队开源的电子商务系统 - eShop
【.net】·【c#】·【开源项目】·【.net core】
追逐时光者10 天前
一个 .NET 开源、免费、功能强大的Windows应用卸载神器
【.net】·【c#】·【开源项目】·【实用工具】
追逐时光者10 天前
2025年这些实用的C#/.NET知识点你都知道吗?
【.net】·【c#】·【.net core】·【拾遗补漏】