Skip to content

Instantly share code, notes, and snippets.

@KyleMit
Last active September 16, 2025 15:16
Show Gist options
  • Save KyleMit/2199c0df74461d3c9fd562838fd72378 to your computer and use it in GitHub Desktop.
Save KyleMit/2199c0df74461d3c9fd562838fd72378 to your computer and use it in GitHub Desktop.
Performance Benchmarks for String Concatenation
| Method | Lines | Mean | Ratio | Allocated |
|--------------------------------- |------ |---------:|------:|-----------:|
| Option_A_Chained_Appends | 10000 | 102.0 us | 0.86 | 935.62 KB |
| Option_B_AppendFormat | 10000 | 204.9 us | 1.73 | 1169.99 KB |
| Option_C_Interpolated_AppendLine | 10000 | 118.8 us | 1.00 | 935.62 KB |
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Running;
public class Program
{
public static void Main(string[] args)
=> BenchmarkRunner.Run<StringBuilderSuite>();
}
[MemoryDiagnoser] // reports allocations, too
[HideColumns(
Column.Error,
Column.StdDev,
Column.RatioSD,
Column.AllocRatio,
Column.Gen0,
Column.Gen1,
Column.Gen2)]
public class StringBuilderSuite
{
// How many lines to build per benchmark. Adjust if you want a longer/shorter run.
[Params(10_000)]
public int Lines;
// Rough preallocation to avoid resize noise; tweak if you change the format a lot.
private int EstimatedPerLine => 24;
[Benchmark]
public string Option_A_Chained_Appends()
{
var sb = new StringBuilder(Lines * EstimatedPerLine);
for (int i = 0; i < Lines; i++)
{
sb.Append("remapping ").Append(i).AppendLine(" synonyms");
}
return sb.ToString();
}
[Benchmark]
public string Option_B_AppendFormat()
{
var sb = new StringBuilder(Lines * EstimatedPerLine);
for (int i = 0; i < Lines; i++)
{
sb.AppendFormat("remapping {0} synonyms", i).AppendLine();
}
return sb.ToString(); // prevent dead-code elimination
}
[Benchmark(Baseline = true)]
public string Option_C_Interpolated_AppendLine()
{
var sb = new StringBuilder(Lines * EstimatedPerLine);
for (int i = 0; i < Lines; i++)
{
// On modern .NET, this uses the interpolated string handler => no intermediate string
sb.AppendLine($"remapping {i} synonyms");
}
return sb.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment