写点什么

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

作者:EquatorCoco
  • 2024-12-23
    福建
  • 本文字数:5037 字

    阅读完需:约 17 分钟

前言


在 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 = 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();        }    }
复制代码


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





说明:

  • 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。如果代码简洁性和易读性更重要,并且拼接次数较少,则可以考虑使用其他方式。


文章转载自:追逐时光者

原文链接:https://www.cnblogs.com/Can-daydayup/p/18622844

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

EquatorCoco

关注

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
C#字符串拼接的几种方式及其性能分析对比_C#_EquatorCoco_InfoQ写作社区