Simple string concatenation for small amounts of strings in .NET 8




Date Added (UTC):

05 Apr 2024 @ 04:17

Date Updated (UTC):

05 Apr 2024 @ 04:17


.NET Version(s):

.NET 8

Tag(s):

#StringConcatenation #Strings


Added By:
Profile Image

Blog   
Ireland    
.NET Developer and tech lead from Ireland!

Benchmark Results:





Benchmark Code:



using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
using System.Text;

namespace Benchmarks
{
    [MemoryDiagnoser]
    [Config(typeof(Config))]
    [SimpleJob(RuntimeMoniker.Net80)]
    [HideColumns(Column.Job, Column.RatioSD, Column.AllocRatio)]
    public class StringConcatSimple
    {
        private class Config : ManualConfig
        {
            public Config()
            {
                SummaryStyle =
                    SummaryStyle.Default.WithRatioStyle(RatioStyle.Percentage);
            }
        }

        private string
            title = "Mr.", firstName = "David", middleName = "Patrick", lastName = "Callan";

        [Benchmark(Baseline = true)]
        public string StringBuilder()
        {
            var stringBuilder =
                new StringBuilder();

            return stringBuilder
                .Append(title).Append(' ')
                .Append(firstName).Append(' ')
                .Append(middleName).Append(' ')
                .Append(lastName).ToString();
        }

        [Benchmark]
        public string StringBuilderExact24()
        {
            var stringBuilder =
                new StringBuilder(24);

            return stringBuilder
                .Append(title).Append(' ')
                .Append(firstName).Append(' ')
                .Append(middleName).Append(' ')
                .Append(lastName).ToString();
        }

        [Benchmark]
        public string StringBuilderEstimate100()
        {
            var stringBuilder =
                new StringBuilder(100);

            return stringBuilder
                .Append(title).Append(' ')
                .Append(firstName).Append(' ')
                .Append(middleName).Append(' ')
                .Append(lastName).ToString();
        }

        [Benchmark]
        public string StringPlus()
        {
            return title + ' ' + firstName + ' ' +
                middleName + ' ' + lastName;
        }

        [Benchmark]
        public string StringFormat()
        {
            return string.Format("{0} {1} {2} {3}",
                title, firstName, middleName, lastName);
        }

        [Benchmark]
        public string StringInterpolation()
        {
            return
            $"{title} {firstName} {middleName} {lastName}";
        }

        [Benchmark]
        public string StringJoin()
        {
            return string.Join(" ", title, firstName,
                middleName, lastName);
        }

        [Benchmark]
        public string StringConcat()
        {
            return string.
                Concat(new string[] { title, " ", firstName, " ", middleName, " ", lastName });
        }
    }
}

// .NET 8
public string StringBuilder()
{
    return new StringBuilder().Append(title).Append(' ').Append(firstName)
        .Append(' ')
        .Append(middleName)
        .Append(' ')
        .Append(lastName)
        .ToString();
}
// .NET 8
public string StringBuilderExact24()
{
    return new StringBuilder(24).Append(title).Append(' ').Append(firstName)
        .Append(' ')
        .Append(middleName)
        .Append(' ')
        .Append(lastName)
        .ToString();
}
// .NET 8
public string StringBuilderEstimate100()
{
    return new StringBuilder(100).Append(title).Append(' ').Append(firstName)
        .Append(' ')
        .Append(middleName)
        .Append(' ')
        .Append(lastName)
        .ToString();
}
// .NET 8
public string StringPlus()
{
    string[] array = new string[7];
    array[0] = title;
    array[1] = " ";
    array[2] = firstName;
    array[3] = " ";
    array[4] = middleName;
    array[5] = " ";
    array[6] = lastName;
    return string.Concat(array);
}
// .NET 8
public string StringFormat()
{
    object[] array = new object[4];
    array[0] = title;
    array[1] = firstName;
    array[2] = middleName;
    array[3] = lastName;
    return string.Format("{0} {1} {2} {3}", array);
}
// .NET 8
public string StringInterpolation()
{
    DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(3, 4);
    defaultInterpolatedStringHandler.AppendFormatted(title);
    defaultInterpolatedStringHandler.AppendLiteral(" ");
    defaultInterpolatedStringHandler.AppendFormatted(firstName);
    defaultInterpolatedStringHandler.AppendLiteral(" ");
    defaultInterpolatedStringHandler.AppendFormatted(middleName);
    defaultInterpolatedStringHandler.AppendLiteral(" ");
    defaultInterpolatedStringHandler.AppendFormatted(lastName);
    return defaultInterpolatedStringHandler.ToStringAndClear();
}
// .NET 8
public string StringJoin()
{
    string[] array = new string[4];
    array[0] = title;
    array[1] = firstName;
    array[2] = middleName;
    array[3] = lastName;
    return string.Join(" ", array);
}
// .NET 8
public string StringConcat()
{
    string[] array = new string[7];
    array[0] = title;
    array[1] = " ";
    array[2] = firstName;
    array[3] = " ";
    array[4] = middleName;
    array[5] = " ";
    array[6] = lastName;
    return string.Concat(array);
}

// .NET 8
.method public hidebysig 
    instance string StringBuilder () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 27 00 00 00 01 5f 01 00 54 02 08 42 61 73
        65 6c 69 6e 65 01
    )
    // Method begins at RVA 0x2050
    // Code size 76 (0x4c)
    .maxstack 2

    // sequence point: (line 42, col 13) to (line 43, col 37) in _
    IL_0000: newobj instance void [System.Runtime]System.Text.StringBuilder::.ctor()
    // sequence point: (line 45, col 13) to (line 49, col 46) in _
    IL_0005: ldarg.0
    IL_0006: ldfld string Benchmarks.StringConcatSimple::title
    IL_000b: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0010: ldc.i4.s 32
    IL_0012: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_0017: ldarg.0
    IL_0018: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001d: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0022: ldc.i4.s 32
    IL_0024: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_0029: ldarg.0
    IL_002a: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_002f: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0034: ldc.i4.s 32
    IL_0036: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_003b: ldarg.0
    IL_003c: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_0041: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0046: callvirt instance string [System.Runtime]System.Object::ToString()
    IL_004b: ret
}
// .NET 8
.method public hidebysig 
    instance string StringBuilderExact24 () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 34 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x20a8
    // Code size 78 (0x4e)
    .maxstack 2

    // sequence point: (line 55, col 13) to (line 56, col 39) in _
    IL_0000: ldc.i4.s 24
    IL_0002: newobj instance void [System.Runtime]System.Text.StringBuilder::.ctor(int32)
    // sequence point: (line 58, col 13) to (line 62, col 46) in _
    IL_0007: ldarg.0
    IL_0008: ldfld string Benchmarks.StringConcatSimple::title
    IL_000d: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0012: ldc.i4.s 32
    IL_0014: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_0019: ldarg.0
    IL_001a: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001f: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0024: ldc.i4.s 32
    IL_0026: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_002b: ldarg.0
    IL_002c: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0031: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0036: ldc.i4.s 32
    IL_0038: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_003d: ldarg.0
    IL_003e: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_0043: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0048: callvirt instance string [System.Runtime]System.Object::ToString()
    IL_004d: ret
}
// .NET 8
.method public hidebysig 
    instance string StringBuilderEstimate100 () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 41 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x2104
    // Code size 78 (0x4e)
    .maxstack 2

    // sequence point: (line 68, col 13) to (line 69, col 40) in _
    IL_0000: ldc.i4.s 100
    IL_0002: newobj instance void [System.Runtime]System.Text.StringBuilder::.ctor(int32)
    // sequence point: (line 71, col 13) to (line 75, col 46) in _
    IL_0007: ldarg.0
    IL_0008: ldfld string Benchmarks.StringConcatSimple::title
    IL_000d: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0012: ldc.i4.s 32
    IL_0014: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_0019: ldarg.0
    IL_001a: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001f: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0024: ldc.i4.s 32
    IL_0026: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_002b: ldarg.0
    IL_002c: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0031: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0036: ldc.i4.s 32
    IL_0038: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(char)
    IL_003d: ldarg.0
    IL_003e: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_0043: callvirt instance class [System.Runtime]System.Text.StringBuilder [System.Runtime]System.Text.StringBuilder::Append(string)
    IL_0048: callvirt instance string [System.Runtime]System.Object::ToString()
    IL_004d: ret
}
// .NET 8
.method public hidebysig 
    instance string StringPlus () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 4e 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x2160
    // Code size 72 (0x48)
    .maxstack 4

    // sequence point: (line 81, col 13) to (line 82, col 45) in _
    IL_0000: ldc.i4.7
    IL_0001: newarr [System.Runtime]System.String
    IL_0006: dup
    IL_0007: ldc.i4.0
    IL_0008: ldarg.0
    IL_0009: ldfld string Benchmarks.StringConcatSimple::title
    IL_000e: stelem.ref
    IL_000f: dup
    IL_0010: ldc.i4.1
    IL_0011: ldstr " "
    IL_0016: stelem.ref
    IL_0017: dup
    IL_0018: ldc.i4.2
    IL_0019: ldarg.0
    IL_001a: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001f: stelem.ref
    IL_0020: dup
    IL_0021: ldc.i4.3
    IL_0022: ldstr " "
    IL_0027: stelem.ref
    IL_0028: dup
    IL_0029: ldc.i4.4
    IL_002a: ldarg.0
    IL_002b: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0030: stelem.ref
    IL_0031: dup
    IL_0032: ldc.i4.5
    IL_0033: ldstr " "
    IL_0038: stelem.ref
    IL_0039: dup
    IL_003a: ldc.i4.6
    IL_003b: ldarg.0
    IL_003c: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_0041: stelem.ref
    IL_0042: call string [System.Runtime]System.String::Concat(string[])
    IL_0047: ret
}
// .NET 8
.method public hidebysig 
    instance string StringFormat () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 55 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x21b4
    // Code size 53 (0x35)
    .maxstack 8

    // sequence point: (line 88, col 13) to (line 89, col 57) in _
    IL_0000: ldstr "{0}
// .NET 8
.method public hidebysig 
    instance string StringInterpolation () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 5c 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x21ec
    // Code size 105 (0x69)
    .maxstack 3
    .locals init (
        [0] valuetype [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler
    )

    // sequence point: (line 95, col 13) to (line 96, col 60) in _
    IL_0000: ldloca.s 0
    IL_0002: ldc.i4.3
    IL_0003: ldc.i4.4
    IL_0004: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::.ctor(int32, int32)
    IL_0009: ldloca.s 0
    IL_000b: ldarg.0
    IL_000c: ldfld string Benchmarks.StringConcatSimple::title
    IL_0011: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted(string)
    IL_0016: ldloca.s 0
    IL_0018: ldstr " "
    IL_001d: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendLiteral(string)
    IL_0022: ldloca.s 0
    IL_0024: ldarg.0
    IL_0025: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_002a: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted(string)
    IL_002f: ldloca.s 0
    IL_0031: ldstr " "
    IL_0036: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendLiteral(string)
    IL_003b: ldloca.s 0
    IL_003d: ldarg.0
    IL_003e: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0043: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted(string)
    IL_0048: ldloca.s 0
    IL_004a: ldstr " "
    IL_004f: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendLiteral(string)
    IL_0054: ldloca.s 0
    IL_0056: ldarg.0
    IL_0057: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_005c: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted(string)
    IL_0061: ldloca.s 0
    IL_0063: call instance string [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::ToStringAndClear()
    IL_0068: ret
}
// .NET 8
.method public hidebysig 
    instance string StringJoin () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 63 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x2261
    // Code size 53 (0x35)
    .maxstack 8

    // sequence point: (line 102, col 13) to (line 103, col 39) in _
    IL_0000: ldstr " "
    IL_0005: ldc.i4.4
    IL_0006: newarr [System.Runtime]System.String
    IL_000b: dup
    IL_000c: ldc.i4.0
    IL_000d: ldarg.0
    IL_000e: ldfld string Benchmarks.StringConcatSimple::title
    IL_0013: stelem.ref
    IL_0014: dup
    IL_0015: ldc.i4.1
    IL_0016: ldarg.0
    IL_0017: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001c: stelem.ref
    IL_001d: dup
    IL_001e: ldc.i4.2
    IL_001f: ldarg.0
    IL_0020: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0025: stelem.ref
    IL_0026: dup
    IL_0027: ldc.i4.3
    IL_0028: ldarg.0
    IL_0029: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_002e: stelem.ref
    IL_002f: call string [System.Runtime]System.String::Join(string, string[])
    IL_0034: ret
}
// .NET 8
.method public hidebysig 
    instance string StringConcat () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 6a 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x2298
    // Code size 72 (0x48)
    .maxstack 4

    // sequence point: (line 109, col 13) to (line 110, col 96) in _
    IL_0000: ldc.i4.7
    IL_0001: newarr [System.Runtime]System.String
    IL_0006: dup
    IL_0007: ldc.i4.0
    IL_0008: ldarg.0
    IL_0009: ldfld string Benchmarks.StringConcatSimple::title
    IL_000e: stelem.ref
    IL_000f: dup
    IL_0010: ldc.i4.1
    IL_0011: ldstr " "
    IL_0016: stelem.ref
    IL_0017: dup
    IL_0018: ldc.i4.2
    IL_0019: ldarg.0
    IL_001a: ldfld string Benchmarks.StringConcatSimple::firstName
    IL_001f: stelem.ref
    IL_0020: dup
    IL_0021: ldc.i4.3
    IL_0022: ldstr " "
    IL_0027: stelem.ref
    IL_0028: dup
    IL_0029: ldc.i4.4
    IL_002a: ldarg.0
    IL_002b: ldfld string Benchmarks.StringConcatSimple::middleName
    IL_0030: stelem.ref
    IL_0031: dup
    IL_0032: ldc.i4.5
    IL_0033: ldstr " "
    IL_0038: stelem.ref
    IL_0039: dup
    IL_003a: ldc.i4.6
    IL_003b: ldarg.0
    IL_003c: ldfld string Benchmarks.StringConcatSimple::lastName
    IL_0041: stelem.ref
    IL_0042: call string [System.Runtime]System.String::Concat(string[])
    IL_0047: ret
}

// .NET 8 (X64)
StringBuilder()
    L0000: push rsi
    L0001: push rbx
    L0002: sub rsp, 0x28
    L0006: mov rbx, rcx
    L0009: mov rcx, 0x7ff93e6e29c0
    L0013: call 0x00007ff99e0fae10
    L0018: mov rsi, rax
    L001b: mov dword ptr [rsi+0x20], 0x7fffffff
    L0022: mov rcx, 0x7ff93e6e3038
    L002c: mov edx, 0x10
    L0031: call 0x00007ff99e0faf30
    L0036: lea rcx, [rsi+8]
    L003a: mov rdx, rax
    L003d: call 0x00007ff99e0fa680
    L0042: mov rdx, [rbx+8]
    L0046: test rdx, rdx
    L0049: je short L005c
    L004b: mov r8d, [rdx+8]
    L004f: add rdx, 0xc
    L0053: mov rcx, rsi
    L0056: call qword ptr [0x7ff93e6dd980]
    L005c: mov ecx, [rsi+0x18]
    L005f: mov rdx, [rsi+8]
    L0063: mov eax, [rdx+8]
    L0066: cmp eax, ecx
    L0068: jbe L010f
    L006e: mov ecx, ecx
    L0070: mov word ptr [rdx+rcx*2+0x10], 0x20
    L0077: inc dword ptr [rsi+0x18]
    L007a: mov rdx, [rbx+0x10]
    L007e: test rdx, rdx
    L0081: je short L0094
    L0083: mov r8d, [rdx+8]
    L0087: add rdx, 0xc
    L008b: mov rcx, rsi
    L008e: call qword ptr [0x7ff93e6dd980]
    L0094: mov ecx, [rsi+0x18]
    L0097: mov rdx, [rsi+8]
    L009b: mov eax, [rdx+8]
    L009e: cmp eax, ecx
    L00a0: jbe L0122
    L00a6: mov ecx, ecx
    L00a8: mov word ptr [rdx+rcx*2+0x10], 0x20
    L00af: inc dword ptr [rsi+0x18]
    L00b2: mov rdx, [rbx+0x18]
    L00b6: test rdx, rdx
    L00b9: je short L00cc
    L00bb: mov r8d, [rdx+8]
    L00bf: add rdx, 0xc
    L00c3: mov rcx, rsi
    L00c6: call qword ptr [0x7ff93e6dd980]
    L00cc: mov ecx, [rsi+0x18]
    L00cf: mov rdx, [rsi+8]
    L00d3: mov eax, [rdx+8]
    L00d6: cmp eax, ecx
    L00d8: jbe short L0132
    L00da: mov ecx, ecx
    L00dc: mov word ptr [rdx+rcx*2+0x10], 0x20
    L00e3: inc dword ptr [rsi+0x18]
    L00e6: mov rdx, [rbx+0x20]
    L00ea: test rdx, rdx
    L00ed: je short L0100
    L00ef: mov r8d, [rdx+8]
    L00f3: add rdx, 0xc
    L00f7: mov rcx, rsi
    L00fa: call qword ptr [0x7ff93e6dd980]
    L0100: mov rcx, rsi
    L0103: add rsp, 0x28
    L0107: pop rbx
    L0108: pop rsi
    L0109: jmp qword ptr [0x7ff93e6e2a28]
    L010f: mov rcx, rsi
    L0112: mov edx, 0x20
    L0117: call qword ptr [0x7ff93e6dd2f0]
    L011d: jmp L007a
    L0122: mov rcx, rsi
    L0125: mov edx, 0x20
    L012a: call qword ptr [0x7ff93e6dd2f0]
    L0130: jmp short L00b2
    L0132: mov rcx, rsi
    L0135: mov edx, 0x20
    L013a: call qword ptr [0x7ff93e6dd2f0]
    L0140: jmp short L00e6
// .NET 8 (X64)
StringBuilderExact24()
    L0000: push rsi
    L0001: push rbx
    L0002: sub rsp, 0x28
    L0006: mov rbx, rcx
    L0009: mov rcx, 0x7ff93e6e29c0
    L0013: call 0x00007ff99e0fae10
    L0018: mov rsi, rax
    L001b: mov rcx, rsi
    L001e: mov edx, 0x18
    L0023: mov r8d, 0x7fffffff
    L0029: call qword ptr [0x7ff93e6dcff0]
    L002f: mov rdx, [rbx+8]
    L0033: test rdx, rdx
    L0036: je short L0049
    L0038: mov r8d, [rdx+8]
    L003c: add rdx, 0xc
    L0040: mov rcx, rsi
    L0043: call qword ptr [0x7ff93e6dd980]
    L0049: mov ecx, [rsi+0x18]
    L004c: mov rdx, [rsi+8]
    L0050: mov eax, [rdx+8]
    L0053: cmp eax, ecx
    L0055: jbe L00fc
    L005b: mov ecx, ecx
    L005d: mov word ptr [rdx+rcx*2+0x10], 0x20
    L0064: inc dword ptr [rsi+0x18]
    L0067: mov rdx, [rbx+0x10]
    L006b: test rdx, rdx
    L006e: je short L0081
    L0070: mov r8d, [rdx+8]
    L0074: add rdx, 0xc
    L0078: mov rcx, rsi
    L007b: call qword ptr [0x7ff93e6dd980]
    L0081: mov ecx, [rsi+0x18]
    L0084: mov rdx, [rsi+8]
    L0088: mov eax, [rdx+8]
    L008b: cmp eax, ecx
    L008d: jbe L010f
    L0093: mov ecx, ecx
    L0095: mov word ptr [rdx+rcx*2+0x10], 0x20
    L009c: inc dword ptr [rsi+0x18]
    L009f: mov rdx, [rbx+0x18]
    L00a3: test rdx, rdx
    L00a6: je short L00b9
    L00a8: mov r8d, [rdx+8]
    L00ac: add rdx, 0xc
    L00b0: mov rcx, rsi
    L00b3: call qword ptr [0x7ff93e6dd980]
    L00b9: mov ecx, [rsi+0x18]
    L00bc: mov rdx, [rsi+8]
    L00c0: mov eax, [rdx+8]
    L00c3: cmp eax, ecx
    L00c5: jbe short L011f
    L00c7: mov ecx, ecx
    L00c9: mov word ptr [rdx+rcx*2+0x10], 0x20
    L00d0: inc dword ptr [rsi+0x18]
    L00d3: mov rdx, [rbx+0x20]
    L00d7: test rdx, rdx
    L00da: je short L00ed
    L00dc: mov r8d, [rdx+8]
    L00e0: add rdx, 0xc
    L00e4: mov rcx, rsi
    L00e7: call qword ptr [0x7ff93e6dd980]
    L00ed: mov rcx, rsi
    L00f0: add rsp, 0x28
    L00f4: pop rbx
    L00f5: pop rsi
    L00f6: jmp qword ptr [0x7ff93e6e2a28]
    L00fc: mov rcx, rsi
    L00ff: mov edx, 0x20
    L0104: call qword ptr [0x7ff93e6dd2f0]
    L010a: jmp L0067
    L010f: mov rcx, rsi
    L0112: mov edx, 0x20
    L0117: call qword ptr [0x7ff93e6dd2f0]
    L011d: jmp short L009f
    L011f: mov rcx, rsi
    L0122: mov edx, 0x20
    L0127: call qword ptr [0x7ff93e6dd2f0]
    L012d: jmp short L00d3
// .NET 8 (X64)
StringBuilderEstimate100()
    L0000: push rsi
    L0001: push rbx
    L0002: sub rsp, 0x28
    L0006: mov rbx, rcx
    L0009: mov rcx, 0x7ff93e6e29c0
    L0013: call 0x00007ff99e0fae10
    L0018: mov rsi, rax
    L001b: mov rcx, rsi
    L001e: mov edx, 0x64
    L0023: mov r8d, 0x7fffffff
    L0029: call qword ptr [0x7ff93e6dcff0]
    L002f: mov rdx, [rbx+8]
    L0033: test rdx, rdx
    L0036: je short L0049
    L0038: mov r8d, [rdx+8]
    L003c: add rdx, 0xc
    L0040: mov rcx, rsi
    L0043: call qword ptr [0x7ff93e6dd980]
    L0049: mov ecx, [rsi+0x18]
    L004c: mov rdx, [rsi+8]
    L0050: mov eax, [rdx+8]
    L0053: cmp eax, ecx
    L0055: jbe L00fc
    L005b: mov ecx, ecx
    L005d: mov word ptr [rdx+rcx*2+0x10], 0x20
    L0064: inc dword ptr [rsi+0x18]
    L0067: mov rdx, [rbx+0x10]
    L006b: test rdx, rdx
    L006e: je short L0081
    L0070: mov r8d, [rdx+8]
    L0074: add rdx, 0xc
    L0078: mov rcx, rsi
    L007b: call qword ptr [0x7ff93e6dd980]
    L0081: mov ecx, [rsi+0x18]
    L0084: mov rdx, [rsi+8]
    L0088: mov eax, [rdx+8]
    L008b: cmp eax, ecx
    L008d: jbe L010f
    L0093: mov ecx, ecx
    L0095: mov word ptr [rdx+rcx*2+0x10], 0x20
    L009c: inc dword ptr [rsi+0x18]
    L009f: mov rdx, [rbx+0x18]
    L00a3: test rdx, rdx
    L00a6: je short L00b9
    L00a8: mov r8d, [rdx+8]
    L00ac: add rdx, 0xc
    L00b0: mov rcx, rsi
    L00b3: call qword ptr [0x7ff93e6dd980]
    L00b9: mov ecx, [rsi+0x18]
    L00bc: mov rdx, [rsi+8]
    L00c0: mov eax, [rdx+8]
    L00c3: cmp eax, ecx
    L00c5: jbe short L011f
    L00c7: mov ecx, ecx
    L00c9: mov word ptr [rdx+rcx*2+0x10], 0x20
    L00d0: inc dword ptr [rsi+0x18]
    L00d3: mov rdx, [rbx+0x20]
    L00d7: test rdx, rdx
    L00da: je short L00ed
    L00dc: mov r8d, [rdx+8]
    L00e0: add rdx, 0xc
    L00e4: mov rcx, rsi
    L00e7: call qword ptr [0x7ff93e6dd980]
    L00ed: mov rcx, rsi
    L00f0: add rsp, 0x28
    L00f4: pop rbx
    L00f5: pop rsi
    L00f6: jmp qword ptr [0x7ff93e6e2a28]
    L00fc: mov rcx, rsi
    L00ff: mov edx, 0x20
    L0104: call qword ptr [0x7ff93e6dd2f0]
    L010a: jmp L0067
    L010f: mov rcx, rsi
    L0112: mov edx, 0x20
    L0117: call qword ptr [0x7ff93e6dd2f0]
    L011d: jmp short L009f
    L011f: mov rcx, rsi
    L0122: mov edx, 0x20
    L0127: call qword ptr [0x7ff93e6dd2f0]
    L012d: jmp short L00d3
// .NET 8 (X64)
StringPlus()
    L0000: push rdi
    L0001: push rsi
    L0002: push rbx
    L0003: sub rsp, 0x20
    L0007: mov rbx, rcx
    L000a: mov rcx, 0x7ff93e5ffb20
    L0014: mov edx, 7
    L0019: call 0x00007ff99e0faf90
    L001e: mov rsi, rax
    L0021: mov rdx, [rbx+8]
    L0025: lea rcx, [rsi+0x10]
    L0029: call 0x00007ff99e0fa680
    L002e: lea rcx, [rsi+0x18]
    L0032: mov rdx, 0x21c163614a8
    L003c: mov rdi, [rdx]
    L003f: mov rdx, rdi
    L0042: call 0x00007ff99e0fa680
    L0047: mov rdx, [rbx+0x10]
    L004b: lea rcx, [rsi+0x20]
    L004f: call 0x00007ff99e0fa680
    L0054: lea rcx, [rsi+0x28]
    L0058: mov rdx, rdi
    L005b: call 0x00007ff99e0fa680
    L0060: mov rdx, [rbx+0x18]
    L0064: lea rcx, [rsi+0x30]
    L0068: call 0x00007ff99e0fa680
    L006d: lea rcx, [rsi+0x38]
    L0071: mov rdx, rdi
    L0074: call 0x00007ff99e0fa680
    L0079: mov rdx, [rbx+0x20]
    L007d: lea rcx, [rsi+0x40]
    L0081: call 0x00007ff99e0fa680
    L0086: mov rcx, rsi
    L0089: add rsp, 0x20
    L008d: pop rbx
    L008e: pop rsi
    L008f: pop rdi
    L0090: jmp qword ptr [0x7ff93e566bb0]
// .NET 8 (X64)
StringFormat()
    L0000: push rsi
    L0001: push rbx
    L0002: sub rsp, 0x38
    L0006: xor eax, eax
    L0008: mov [rsp+0x28], rax
    L000d: mov rbx, rcx
    L0010: mov rcx, 0x7ff93e4ac4d8
    L001a: mov edx, 4
    L001f: call 0x00007ff99e0faf90
    L0024: mov rsi, rax
    L0027: mov rdx, [rbx+8]
    L002b: lea rcx, [rsi+0x10]
    L002f: call 0x00007ff99e0fa680
    L0034: mov rdx, [rbx+0x10]
    L0038: lea rcx, [rsi+0x18]
    L003c: call 0x00007ff99e0fa680
    L0041: mov rdx, [rbx+0x18]
    L0045: lea rcx, [rsi+0x20]
    L0049: call 0x00007ff99e0fa680
    L004e: mov rdx, [rbx+0x20]
    L0052: lea rcx, [rsi+0x28]
    L0056: call 0x00007ff99e0fa680
    L005b: add rsi, 0x10
    L005f: mov r8d, 4
    L0065: mov rdx, 0x21c16c654e8
    L006f: mov rdx, [rdx]
    L0072: mov [rsp+0x28], rsi
    L0077: mov [rsp+0x30], r8d
    L007c: lea r8, [rsp+0x28]
    L0081: xor ecx, ecx
    L0083: call qword ptr [0x7ff93e566c88]
    L0089: nop
    L008a: add rsp, 0x38
    L008e: pop rbx
    L008f: pop rsi
    L0090: ret
// .NET 8 (X64)
StringInterpolation()
    L0000: push r15
    L0002: push r14
    L0004: push r13
    L0006: push rdi
    L0007: push rsi
    L0008: push rbp
    L0009: push rbx
    L000a: sub rsp, 0x50
    L000e: xor eax, eax
    L0010: mov [rsp+0x28], rax
    L0015: vxorps xmm4, xmm4, xmm4
    L0019: vmovdqa [rsp+0x30], xmm4
    L001f: vmovdqa [rsp+0x40], xmm4
    L0025: mov rbx, rcx
    L0028: mov rcx, 0x21c16c02000
    L0032: mov rcx, [rcx]
    L0035: mov edx, 0x100
    L003a: call qword ptr [0x7ff93e863990]
    L0040: mov [rsp+0x30], rax
    L0045: test rax, rax
    L0048: je L02e7
    L004e: lea rsi, [rax+0x10]
    L0052: mov edi, [rax+8]
    L0055: mov [rsp+0x40], rsi
    L005a: mov [rsp+0x48], edi
    L005e: xor r8d, r8d
    L0061: mov [rsp+0x38], r8d
    L0066: mov byte ptr [rsp+0x3c], 0
    L006b: mov rbp, [rbx+8]
    L006f: cmp byte ptr [rsp+0x3c], 0
    L0074: jne L02f0
    L007a: test rbp, rbp
    L007d: je L02f0
    L0083: mov r8d, [rsp+0x38]
    L0088: cmp r8d, [rsp+0x48]
    L008d: ja L0383
    L0093: mov rcx, [rsp+0x40]
    L0098: mov edx, r8d
    L009b: lea rcx, [rcx+rdx*2]
    L009f: mov edx, [rsp+0x48]
    L00a3: sub edx, r8d
    L00a6: cmp [rbp+8], edx
    L00a9: ja L02f0
    L00af: lea rdx, [rbp+0xc]
    L00b3: mov r8d, [rbp+8]
    L00b7: add r8, r8
    L00ba: call qword ptr [0x7ff93e615b78]
    L00c0: mov r8d, [rsp+0x38]
    L00c5: add r8d, [rbp+8]
    L00c9: mov [rsp+0x38], r8d
    L00ce: mov r8d, [rsp+0x38]
    L00d3: mov ecx, [rsp+0x48]
    L00d7: cmp r8d, ecx
    L00da: ja L0383
    L00e0: mov rdx, [rsp+0x40]
    L00e5: mov eax, r8d
    L00e8: lea rdx, [rdx+rax*2]
    L00ec: sub ecx, r8d
    L00ef: cmp ecx, 1
    L00f2: jb L0303
    L00f8: mov r8, 0x21c163614a8
    L0102: mov r14, [r8]
    L0105: lea r8, [r14+0xc]
    L0109: movzx ecx, word ptr [r8]
    L010d: mov [rdx], cx
    L0110: mov r8d, [rsp+0x38]
    L0115: inc r8d
    L0118: mov [rsp+0x38], r8d
    L011d: mov r15, [rbx+0x10]
    L0121: cmp byte ptr [rsp+0x3c], 0
    L0126: jne L032d
    L012c: test r15, r15
    L012f: je L032d
    L0135: mov r8d, [rsp+0x38]
    L013a: cmp r8d, [rsp+0x48]
    L013f: ja L0383
    L0145: mov rcx, [rsp+0x40]
    L014a: mov edx, r8d
    L014d: lea rcx, [rcx+rdx*2]
    L0151: mov edx, [rsp+0x48]
    L0155: sub edx, r8d
    L0158: cmp [r15+8], edx
    L015c: ja L032d
    L0162: lea rdx, [r15+0xc]
    L0166: mov r8d, [r15+8]
    L016a: add r8, r8
    L016d: call qword ptr [0x7ff93e615b78]
    L0173: mov r8d, [rsp+0x38]
    L0178: add r8d, [r15+8]
    L017c: mov [rsp+0x38], r8d
    L0181: mov r8d, [rsp+0x38]
    L0186: mov ecx, [rsp+0x48]
    L018a: cmp r8d, ecx
    L018d: ja L0383
    L0193: mov rdx, [rsp+0x40]
    L0198: mov eax, r8d
    L019b: lea rdx, [rdx+rax*2]
    L019f: sub ecx, r8d
    L01a2: cmp ecx, 1
    L01a5: jb L0340
    L01ab: lea r8, [r14+0xc]
    L01af: movzx ecx, word ptr [r8]
    L01b3: mov [rdx], cx
    L01b6: mov r8d, [rsp+0x38]
    L01bb: inc r8d
    L01be: mov [rsp+0x38], r8d
    L01c3: mov r13, [rbx+0x18]
    L01c7: cmp byte ptr [rsp+0x3c], 0
    L01cc: jne L035d
    L01d2: test r13, r13
    L01d5: je L035d
    L01db: mov r8d, [rsp+0x38]
    L01e0: cmp r8d, [rsp+0x48]
    L01e5: ja L0383
    L01eb: mov rcx, [rsp+0x40]
    L01f0: mov edx, r8d
    L01f3: lea rcx, [rcx+rdx*2]
    L01f7: mov edx, [rsp+0x48]
    L01fb: sub edx, r8d
    L01fe: cmp [r13+8], edx
    L0202: ja L035d
    L0208: lea rdx, [r13+0xc]
    L020c: mov r8d, [r13+8]
    L0210: add r8, r8
    L0213: call qword ptr [0x7ff93e615b78]
    L0219: mov r8d, [rsp+0x38]
    L021e: add r8d, [r13+8]
    L0222: mov [rsp+0x38], r8d
    L0227: mov r8d, [rsp+0x38]
    L022c: mov ecx, [rsp+0x48]
    L0230: cmp r8d, ecx
    L0233: ja L0383
    L0239: mov rdx, [rsp+0x40]
    L023e: mov eax, r8d
    L0241: lea rdx, [rdx+rax*2]
    L0245: sub ecx, r8d
    L0248: cmp ecx, 1
    L024b: jb L0370
    L0251: add r14, 0xc
    L0255: movzx r8d, word ptr [r14]
    L0259: mov [rdx], r8w
    L025d: mov r8d, [rsp+0x38]
    L0262: inc r8d
    L0265: mov [rsp+0x38], r8d
    L026a: mov r14, [rbx+0x20]
    L026e: cmp byte ptr [rsp+0x3c], 0
    L0273: jne L038a
    L0279: test r14, r14
    L027c: je L038a
    L0282: mov r8d, [rsp+0x38]
    L0287: cmp r8d, [rsp+0x48]
    L028c: ja L0383
    L0292: mov rcx, [rsp+0x40]
    L0297: mov edx, r8d
    L029a: lea rcx, [rcx+rdx*2]
    L029e: mov edx, [rsp+0x48]
    L02a2: sub edx, r8d
    L02a5: cmp [r14+8], edx
    L02a9: ja L038a
    L02af: lea rdx, [r14+0xc]
    L02b3: mov r8d, [r14+8]
    L02b7: add r8, r8
    L02ba: call qword ptr [0x7ff93e615b78]
    L02c0: mov ecx, [rsp+0x38]
    L02c4: add ecx, [r14+8]
    L02c8: mov [rsp+0x38], ecx
    L02cc: lea rcx, [rsp+0x28]
    L02d1: call qword ptr [0x7ff93e8069d0]
    L02d7: nop
    L02d8: add rsp, 0x50
    L02dc: pop rbx
    L02dd: pop rbp
    L02de: pop rsi
    L02df: pop rdi
    L02e0: pop r13
    L02e2: pop r14
    L02e4: pop r15
    L02e6: ret
    L02e7: xor esi, esi
    L02e9: xor edi, edi
    L02eb: jmp L0055
    L02f0: lea rcx, [rsp+0x28]
    L02f5: mov rdx, rbp
    L02f8: call qword ptr [0x7ff93e806ad8]
    L02fe: jmp L00ce
    L0303: mov rdx, 0x21c163614a8
    L030d: mov r14, [rdx]
    L0310: mov rdx, r14
    L0313: lea rcx, [rsp+0x28]
    L0318: call qword ptr [0x7ff93e806b80]
    L031e: mov r15, [rbx+0x10]
    L0322: cmp byte ptr [rsp+0x3c], 0
    L0327: je L012c
    L032d: lea rcx, [rsp+0x28]
    L0332: mov rdx, r15
    L0335: call qword ptr [0x7ff93e806ad8]
    L033b: jmp L0181
    L0340: mov rdx, r14
    L0343: lea rcx, [rsp+0x28]
    L0348: call qword ptr [0x7ff93e806b80]
    L034e: mov r13, [rbx+0x18]
    L0352: cmp byte ptr [rsp+0x3c], 0
    L0357: je L01d2
    L035d: lea rcx, [rsp+0x28]
    L0362: mov rdx, r13
    L0365: call qword ptr [0x7ff93e806ad8]
    L036b: jmp L0227
    L0370: mov rdx, r14
    L0373: lea rcx, [rsp+0x28]
    L0378: call qword ptr [0x7ff93e806b80]
    L037e: jmp L026a
    L0383: call qword ptr [0x7ff93e8edcc8]
    L0389: int3
    L038a: lea rcx, [rsp+0x28]
    L038f: mov rdx, r14
    L0392: call qword ptr [0x7ff93e806ad8]
    L0398: jmp L02cc
// .NET 8 (X64)
StringJoin()
    L0000: push rsi
    L0001: push rbx
    L0002: sub rsp, 0x48
    L0006: xor eax, eax
    L0008: mov [rsp+0x28], rax
    L000d: vxorps xmm4, xmm4, xmm4
    L0011: vmovdqa [rsp+0x30], xmm4
    L0017: mov [rsp+0x40], rax
    L001c: mov rbx, rcx
    L001f: mov rcx, 0x7ff93e5ffb20
    L0029: mov edx, 4
    L002e: call 0x00007ff99e0faf90
    L0033: mov rsi, rax
    L0036: mov rdx, [rbx+8]
    L003a: lea rcx, [rsi+0x10]
    L003e: call 0x00007ff99e0fa680
    L0043: mov rdx, [rbx+0x10]
    L0047: lea rcx, [rsi+0x18]
    L004b: call 0x00007ff99e0fa680
    L0050: mov rdx, [rbx+0x18]
    L0054: lea rcx, [rsi+0x20]
    L0058: call 0x00007ff99e0fa680
    L005d: mov rdx, [rbx+0x20]
    L0061: lea rcx, [rsi+0x28]
    L0065: call 0x00007ff99e0fa680
    L006a: mov rcx, 0x21c163614a8
    L0074: mov rcx, [rcx]
    L0077: add rcx, 0xc
    L007b: add rsi, 0x10
    L007f: mov edx, 4
    L0084: mov [rsp+0x38], rcx
    L0089: mov dword ptr [rsp+0x40], 1
    L0091: mov [rsp+0x28], rsi
    L0096: mov [rsp+0x30], edx
    L009a: lea rcx, [rsp+0x38]
    L009f: lea rdx, [rsp+0x28]
    L00a4: call qword ptr [0x7ff93e566e68]
    L00aa: nop
    L00ab: add rsp, 0x48
    L00af: pop rbx
    L00b0: pop rsi
    L00b1: ret
// .NET 8 (X64)
StringConcat()
    L0000: push rdi
    L0001: push rsi
    L0002: push rbx
    L0003: sub rsp, 0x20
    L0007: mov rbx, rcx
    L000a: mov rcx, 0x7ff93e5ffb20
    L0014: mov edx, 7
    L0019: call 0x00007ff99e0faf90
    L001e: mov rsi, rax
    L0021: mov rdx, [rbx+8]
    L0025: lea rcx, [rsi+0x10]
    L0029: call 0x00007ff99e0fa680
    L002e: lea rcx, [rsi+0x18]
    L0032: mov rdx, 0x21c163614a8
    L003c: mov rdi, [rdx]
    L003f: mov rdx, rdi
    L0042: call 0x00007ff99e0fa680
    L0047: mov rdx, [rbx+0x10]
    L004b: lea rcx, [rsi+0x20]
    L004f: call 0x00007ff99e0fa680
    L0054: lea rcx, [rsi+0x28]
    L0058: mov rdx, rdi
    L005b: call 0x00007ff99e0fa680
    L0060: mov rdx, [rbx+0x18]
    L0064: lea rcx, [rsi+0x30]
    L0068: call 0x00007ff99e0fa680
    L006d: lea rcx, [rsi+0x38]
    L0071: mov rdx, rdi
    L0074: call 0x00007ff99e0fa680
    L0079: mov rdx, [rbx+0x20]
    L007d: lea rcx, [rsi+0x40]
    L0081: call 0x00007ff99e0fa680
    L0086: mov rcx, rsi
    L0089: add rsp, 0x20
    L008d: pop rbx
    L008e: pop rsi
    L008f: pop rdi
    L0090: jmp qword ptr [0x7ff93e566bb0]


Benchmark Description:


Benchmark comparing common approaches for string concatenation of only a couple of strings including interpolation, string.Format, StringBuilder etc. We can see StringBuilder is, at least for this benchmark run, the slowest except for string.Format, Keep this in mind if you ever hear the "_always use StringBuilder_" line on social media or blogs. String.Join is the fastest, while interpolation is super efficient as far as memory is concerned.

The provided benchmark code is designed to measure and compare the performance of different methods for concatenating strings in C#. It uses the BenchmarkDotNet library, a powerful tool for benchmarking .NET applications. The benchmarks are configured to run on the .NET 8.0 runtime, indicating that they are intended for applications targeting the latest version of the .NET platform at the time of writing. The configuration hides certain columns in the output to focus on the most relevant metrics, and it sets a custom summary style to display ratio information as percentages. Below is an overview of each benchmark method, including the rationale behind it and the specific performance aspect it is designed to test: ### 1. `StringBuilder()` - **Purpose**: Measures the performance of string concatenation using the `StringBuilder` class without pre-setting the capacity. - **Importance**: This method tests how well `StringBuilder` performs when it needs to dynamically resize its internal buffer to accommodate the concatenated strings. It's a common scenario when the final size of the concatenated string is unknown. - **Expected Insights**: This benchmark will show how efficient `StringBuilder` is in handling string concatenations without initial capacity optimization. It serves as a baseline for comparing other methods. ### 2. `StringBuilderExact24()` - **Purpose**: Measures the performance of string concatenation using the `StringBuilder` class with the exact initial capacity needed for the final string. - **Importance**: Pre-setting the `StringBuilder` capacity to the exact size needed can significantly improve performance by eliminating the need for internal buffer resizing. This method tests the best-case scenario for `StringBuilder`. - **Expected Insights**: This benchmark is expected to demonstrate the performance benefits of optimizing `StringBuilder`'s initial capacity. It should be faster than the baseline `StringBuilder` method. ### 3. `StringBuilderEstimate100()` - **Purpose**: Similar to `StringBuilderExact24()`, but with an overestimated initial capacity. - **Importance**: This method tests the impact of overestimating the `StringBuilder`'s initial capacity. It's relevant for scenarios where the exact size isn't known, but an estimate is possible. - **Expected Insights**: The results will show how performance is affected by overestimating the capacity. It's likely to be faster than the baseline but may not offer significant advantages over `StringBuilderExact24()`. ### 4. `StringPlus()` - **Purpose**: Measures the performance of string concatenation using the `+` operator. - **Importance**: The `+` operator is the simplest way to concatenate strings but can be inefficient for multiple concatenations due to the creation of intermediate strings. - **Expected Insights**: This benchmark will likely show that using the `+` operator is less efficient than using `StringBuilder`, especially as the number of strings increases. ### 5. `StringFormat()` - **Purpose**: Measures the performance of string concatenation using `string.Format()`. - **Importance**: `string.Format()` is useful for creating formatted strings. This benchmark tests its performance for concatenation purposes. - **Expected Insights**: The method might be slower than `StringBuilder` due to parsing the format string and the overhead of method invocation. ### 6. `StringInterpolation()` - **Purpose**: Measures the performance of string concatenation using string interpolation. - **Importance**: String interpolation is a more readable and concise way to concatenate strings, introduced in C# 6. This benchmark assesses its performance. - **Expected Insights**: This method's performance could be similar to `StringFormat()`, as string interpolation is compiled to a `string.Format()` call under the hood. ### 7. `StringJoin()` - **Purpose**: Measures the performance of concatenating strings using `string.Join()`. - **Importance**: `string.Join()` is designed for concatenating an array of strings with a separator and can be more efficient than using the `+` operator in some cases. - **Expected Insights**: This benchmark will show how `string.Join()` performs compared to other methods, potentially offering a balance between readability and performance. ### 8. `StringConcat()` - **Purpose**: Measures the performance of concatenating strings using `string.Concat()`. - **Importance**: `string.Concat()` is a versatile method that can concatenate an array of strings. It's intended to be efficient for concatenating multiple strings. - **Expected Insights**: The performance of `string.Concat()` should be competitive with other efficient methods like `StringBuilder`, especially for a known number of strings. By running these benchmarks, developers can gain insights into the most efficient methods for string concatenation in different scenarios, helping them write more performant C# code.


Benchmark Comments: