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
}
}
作者名称:追逐时光者
作者简介:一个热爱编程、善于分享、喜欢学习、探索、尝试新事物和新技术的全栈软件工程师。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如果该篇文章对您有帮助的话,可以点一下右下角的【♥推荐♥】,希望能够持续的为大家带来好的技术文章,文中可能存在描述不正确的地方,欢迎指正或补充,不胜感激。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体