.NET9 实现字符串拼接(StringConcatenation)性能测试

为了评估 .NET9 平台上使用 C# 中不同字符串拼接操作的性能表现,我们可以使用 BenchmarkDotNet 这一强大的开源库来构建科学且可重复的基准测试。

  • BenchmarkDotNet 能够自动处理诸如 JIT 编译、预热(Warm-up)、运行次数控制、统计误差分析等底层细节,确保测试结果具有高度准确性与可比性。

.NET9 中,使用 C# 字符串拼接的常见方式包括:

  1. 使用 + 运算符
  2. 使用 string.Concat
  3. 使用 string.Format
  4. 使用插值字符串 $"{variable}"
  5. 使用 StringBuilder

为了满足大家对性能的需求,我会创建两个类:

  • StringConcatenationOperations.cs:包含各种字符串拼接操作的实现。
  • StringConcatenationBenchmark.cs:使用 BenchmarkDotNet 对这些操作进行基准测试。

以下是具体的代码实现。


项目准备

  • 项目信息
xml 复制代码
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Datadog.Trace.BenchmarkDotNet" Version="2.61.0" />
  </ItemGroup>

</Project>
  • StringConcatenationOperations
csharp 复制代码
// ====================================================
// 字符串拼接实现:在 .NET 中,字符串拼接的常见方式
// ====================================================

using System.Text;

namespace BenchmarkTest.examples.StringConcatenation;

internal static class StringConcatenationOperations
{
    // 使用 + 运算符
    public static string UsePlusOperator(string a, string b, string c)
    {
        return a + b + c;
    }

    // 使用 string.Concat
    public static string UseStringConcat(string a, string b, string c)
    {
        return string.Concat(a, b, c);
    }

    // 使用 string.Format
    public static string UseStringFormat(string a, string b, string c)
    {
        return string.Format("{0}{1}{2}", a, b, c);
    }

    // 使用插值字符串 $"{variable}"
    public static string UseStringInterpolation(string a, string b, string c)
    {
        return $"{a}{b}{c}";
    }

    // 使用 StringBuilder
    public static string UseStringBuilder(string a, string b, string c)
    {
        var sb = new StringBuilder();
        sb.Append(a);
        sb.Append(b);
        sb.Append(c);
        return sb.ToString();
    }
}
  • StringConcatenationBenchmark
csharp 复制代码
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running;
using Datadog.Trace.BenchmarkDotNet;

namespace BenchmarkTest.examples.StringConcatenation;

[DatadogDiagnoser]
[MemoryDiagnoser]
public class StringConcatenationBenchmark
{
    private const string A = "Hello";
    private const string B = " ";
    private const string C = "World";

    [Benchmark]
    public string PlusOperator()
    {
        return StringConcatenationOperations.UsePlusOperator(A, B, C);
    }

    [Benchmark]
    public string StringConcat()
    {
        return StringConcatenationOperations.UseStringConcat(A, B, C);
    }

    [Benchmark]
    public string StringFormat()
    {
        return StringConcatenationOperations.UseStringFormat(A, B, C);
    }

    [Benchmark]
    public string StringInterpolation()
    {
        return StringConcatenationOperations.UseStringInterpolation(A, B, C);
    }

    [Benchmark]
    public string StringBuilder()
    {
        return StringConcatenationOperations.UseStringBuilder(A, B, C);
    }

    public static void Run(IConfig config)
    {
        var summary = BenchmarkRunner.Run<StringConcatenationBenchmark>(config);
        Console.WriteLine(summary);
    }
}
  • Program.cs 中运行基准测试
csharp 复制代码
using BenchmarkDotNet.Configs;
using Datadog.Trace.BenchmarkDotNet;
using BenchmarkTest.examples.StringConcatenation;

Console.WriteLine("Hello, BenchmarkDotNetTest!");

var config = DefaultConfig.Instance.WithDatadog();
StringConcatenationBenchmark.Run(config);
  • 运行测试

在项目根目录,使用 pwsh 终端输入命令:

csharp 复制代码
dotnet run -c Release

输出信息:

以下是对 BenchmarkDotNet 测试结果的详细分析:


🧪 测试环境信息

  • BenchmarkDotNet 版本 : v0.13.2
  • 操作系统 : Windows 11 (10.0.26100.4484)
  • .NET SDK : 9.0.301
  • 运行时 : .NET 9.0.6 (9.0.625.26613), X64 AOT AVX2
  • JIT 编译器 : RyuJIT AVX2

📊 基准测试结果

方法名 平均耗时(Mean) 误差范围(Error) 标准差(StdDev) GC Gen0 次数 内存分配
PlusOperator 21.01 ns 0.233 ns 0.207 ns 0.0306 48 B
StringConcat 21.06 ns 0.493 ns 0.606 ns 0.0306 48 B
StringFormat 78.65 ns 1.389 ns 1.300 ns 0.0305 48 B
StringInterpolation 20.88 ns 0.460 ns 0.529 ns 0.0306 48 B
StringBuilder 35.37 ns 0.769 ns 1.175 ns 0.0969 152 B

🔍 逐项分析

1. + 运算符拼接 (PlusOperator)
  • 平均耗时: 21.01 ns
  • 内存分配: 48 字节
  • 特点 :
    • 简洁直观,适合少量字符串拼接。
    • 在编译时会自动优化为 string.Concat
  • 结论: 性能优秀,适合简单拼接场景。
2. string.Concat (StringConcat)
  • 平均耗时: 21.06 ns
  • 内存分配: 48 字节
  • 特点 :
    • 直接调用底层方法,性能与 + 相当。
    • 更加显式地表达意图,适合对性能敏感或需要明确控制拼接逻辑的代码。
  • 结论 : 和 + 类似,但更推荐用于多参数拼接。
3. string.Format (StringFormat)
  • 平均耗时: 78.65 ns
  • 内存分配: 48 字节
  • 特点 :
    • 支持格式化字符串,适合需要插入变量和格式控制的场景。
    • 由于涉及解析格式字符串,性能较差。
  • 结论: 如果需要格式化,可以使用;否则建议避免。
4. 插值字符串 (StringInterpolation)
  • 平均耗时: 20.88 ns
  • 内存分配: 48 字节
  • 特点 :
    • C# 6 引入的新特性,语法简洁、可读性高。
    • 实际上会被编译为 string.Format 或直接内联为 string.Concat
  • 结论: 性能优异,同时具备良好的可读性,推荐使用。
5. StringBuilder (StringBuilder)
  • 平均耗时: 35.37 ns
  • 内存分配: 152 字节
  • 特点 :
    • 适用于频繁修改或大量拼接的场景(如循环中拼接字符串)。
    • 初始化和操作有一定开销,不适合一次性小规模拼接。
  • 结论: 多次拼接时优势明显,单次拼接不推荐。

⚠️ 警告信息

  • MultimodalDistribution(多峰分布)
    • StringBuilder 方法的执行时间分布呈现双峰(bimodal),说明其性能波动较大。
    • 可能原因:GC 影响、缓存命中率变化或其他外部因素。

⚠️ 提示信息

  • Outliers(异常值)
    • PlusOperatorStringFormatStringInterpolation 都检测到了一些性能异常值。
    • 通常由系统负载、GC 操作或其他临时干扰引起。
    • 建议多次运行以确保数据稳定性。

📌 总结建议

使用场景 推荐方式 原因
简单拼接 +string.Concat 性能最佳,语法简洁
需要格式化输出 string.Format 功能强大,但性能略差
提高可读性和现代写法 插值字符串 $"{a}{b}" 性能接近最优,语法清晰
循环拼接或大量拼接 StringBuilder 减少内存分配,避免频繁创建新字符串
高频调用的小规模拼接 避免使用 StringBuilder 初始开销大,小规模拼接时不划算

如果你希望进一步优化测试,比如增加样本数量、调整测试参数,或者测试不同长度的字符串拼接,我可以帮助你修改基准测试代码。欢迎继续提问!

相关推荐
试着5 小时前
零基础学习性能测试第五章:Tomcat的性能分析与调优-Tomcat原理,核心配置项,性能瓶颈分析,调优
学习·零基础·tomcat·性能测试
试着8 小时前
零基础学习性能测试第五章:JVM性能分析与调优-垃圾回收器的分类与回收
jvm·学习·零基础·性能测试·垃圾回收器
追逐时光者10 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 48 期(2025年7.21-7.27)
后端·.net
唐青枫1 天前
C#.NET dapper 详解
c#·.net
Maybe_ch1 天前
.NET-键控服务依赖注入
开发语言·c#·.net
liulilittle1 天前
C++/CLI与标准C++的语法差异(一)
开发语言·c++·.net·cli·clr·托管·原生
界面开发小八哥1 天前
界面组件DevExpress WPF中文教程:Grid - 如何过滤节点?
.net·wpf·界面控件·devexpress·ui开发
SEO-狼术2 天前
List & Label now includes Crack
.net
追逐时光者3 天前
推荐 6 款基于 .NET 开源的串口调试工具,调试效率提升利器!
后端·.net