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

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

前言

在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
    }
}

目录
打赏
0
6
6
0
194
分享
相关文章
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
150 8
C# 去掉字符串最后一个字符的 4 种方法
在实际业务中,我们经常会遇到在循环中拼接字符串的场景,循环结束之后拼接得到的字符串的最后一个字符往往需要去掉,看看 C# 提供了哪4种方法可以高效去掉字符串的最后一个字符
526 0
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
45 11
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
62 10
C# 爬虫技术:京东视频内容抓取的实战案例分析
C# 爬虫技术:京东视频内容抓取的实战案例分析
技术心得记录:深入分析C#键盘勾子(Hook)拦截器,屏蔽键盘活动的详解
技术心得记录:深入分析C#键盘勾子(Hook)拦截器,屏蔽键盘活动的详解
|
6月前
|
C# 一分钟浅谈:字符串操作与正则表达式
本文详细介绍C#中的字符串操作与正则表达式应用,涵盖字符串拼接、分割、查找及替换等基础操作,并通过实例讲解正则表达式的模式匹配、文本替换与分组捕获技巧。同时,文章还探讨了性能优化、复杂度管理和安全性等问题及解决策略,助你提升编程效率,应对实际开发挑战。
110 0
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
|
9月前
|
C#
C# 中的字符与字符串
C# 中的字符与字符串
|
4月前
|
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
72 3