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

 更新时间:2024年12月23日 08:37:53   作者:追逐时光者  
在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();
        }
    }

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

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.Format、String.Concat和String.Join)在性能上相对较差,因为它们会导致多次内存分配和复制。

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

以上就是C#中字符串拼接方式及其性能分析对比的详细内容,更多关于C#字符串拼接的资料请关注脚本之家其它相关文章!

相关文章

  • C# Winform消息通知系统托盘气泡提示框ToolTip控件

    C# Winform消息通知系统托盘气泡提示框ToolTip控件

    这篇文章主要为大家介绍了C#或Winform中的消息通知之系统托盘的气泡提示框窗口(系统toast通知)、ToolTip控件和ToolTipText属性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 使用C#与SQL Server数据库进行交互的详细流程

    使用C#与SQL Server数据库进行交互的详细流程

    本文详细介绍了如何使用Visual Studio创建Windows窗体应用程序连接本地SQL Server数据库,并实现数据插入、查询和删除等功能,通过步骤说明和代码示例,展示了如何使用DataGridView控件和按钮控件与数据库进行交互,文章还总结了易错点,需要的朋友可以参考下
    2025-11-11
  • c# 如何实现不同进程之间的通信

    c# 如何实现不同进程之间的通信

    这篇文章主要介绍了c# 如何实现不同进程之间的通信,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-11-11
  • WinForms中主要控件的详细使用教程

    WinForms中主要控件的详细使用教程

    WinForms (Windows Forms) 是 Microsoft 提供的用于构建 Windows 桌面应用程序的框架,它提供了丰富的控件集合,可以满足各种 UI 设计需求,以下是 WinForms 中主要控件的详细使用教程,,需要的朋友可以参考下
    2025-05-05
  • c#实现抓取高清美女妹纸图片

    c#实现抓取高清美女妹纸图片

    本文给大家分享的是一则使用c#实现抓取网络高清美女妹纸图片的代码,这么好的东西,当然不能独享,推荐给小伙伴们。
    2015-03-03
  • C#中Region、Exclude的用法小结

    C#中Region、Exclude的用法小结

    本文主要介绍了C#中Region、Exclude的用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • Unity实现大转盘的简单笔记

    Unity实现大转盘的简单笔记

    这篇文章主要为大家分享了Unity实现大转盘的简单笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • 关于ASP网页无法打开的解决方案

    关于ASP网页无法打开的解决方案

    asp网页实际上就是动态网页,是在服务端执行和解析的。有时也很奇怪,经常遇到asp网页无法打开的情况,下面小编给大家整理些关于asp网页无法打开的解决方案,需要的朋友可以参考下
    2015-08-08
  • 浅谈c#开发者应该了解的15个特性

    浅谈c#开发者应该了解的15个特性

    本文列举了15个值得了解的C#特性,旨在让.NET开发人员更好的使用C#语言进行开发工作。
    2021-05-05
  • c#检测端口是否被占用的简单实例

    c#检测端口是否被占用的简单实例

    这篇文章主要介绍了c#检测端口是否被占用的简单实例,有需要的朋友可以参考一下
    2013-12-12

最新评论