.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 初始开销大,小规模拼接时不划算

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

相关推荐
追逐时光者11 小时前
一个基于 .NET 开源、功能强大的分布式微服务开发框架
后端·.net
笺上知微11 小时前
Serilog基于Seq开源框架实现日志分析
.net
百锦再11 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
CodeCraft Studio12 小时前
【能源与流程工业案例】KBC借助TeeChart 打造工业级数据可视化平台
java·信息可视化·.net·能源·teechart·工业可视化·工业图表
一个帅气昵称啊13 小时前
使用微软Agent Framework .NET构建智能代理应用
microsoft·flask·.net
一个天蝎座 白勺 程序猿14 小时前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库
时光追逐者15 小时前
一个使用 WPF 开发的 Diagram 画板工具(包含流程图FlowChart,思维导图MindEditor)
c#·.net·wpf·流程图
我是唐青枫15 小时前
C#.NET FluentValidation 全面解析:优雅实现对象验证
c#·.net
VB.Net16 小时前
VB.Net循序渐进(第二版)
开发语言·.net·vb.net