"Use always a StringBuilder" - Internet myths

From time to time I read on various channels that you should always use a StringBuilder because it is faster and uses fewer allocations. If you read the term always then you should be even more careful.

In this blog post, I want to show you that this is not true and what alternatives are (even faster than the StringBuilder).

Why StringBuilder in the first place?

Let's discuss what the StringBuilder tries to solve. As I already discussed a while back I will quote myself here:

Why concatenating strings is slow and takes a lot of allocations. The sole reason is immutability. strings are immutable. That means if you want to change a string or append another to our string you have to create a new one. This is a conscious design decision of the C# team. Other languages like Swift or C/C++ have mutable strings! Java has immutable strings as well!

Taken from: Create a low allocation and faster StringBuilder - Span in Action

Benchmark

Let's make the test: We compare a normal + against the StringBuilder:

[Benchmark]
public string StringBuilder()
{
    var builder = new StringBuilder();
    for (var i = 0; i < Iterations; i++)
        builder.Append(TextToAppend);

    return builder.ToString();
}

[Benchmark]
public string Concat()
{
    var output = string.Empty;
    for (var i = 0; i < Iterations; i++)
        output += TextToAppend;

    return output;
}

And here are the results: Concat vs Builder

We can see that for lots of operations the StringBuilder outperforms the + operator (also string.Concat for that matter). But we can also see for a very small amount of concatenations the picture shifts. Concat uses fewer allocations and is faster. So I guess we debunked the always part. But we can take this even further:

Use List<string>

Often times a simple list of strings can be easier and faster. A full-blown StringBuilder does more than append some strings. You can also remove parts of the string or insert them somewhere in the middle. If you don't need this, a List<string> can be equally powerful or even faster.

Benchmark]
public string ListOfStrings()
{
    var list = new List<string>();
    for(var i = 0; i < Iterations;i++)
        list.Add(TextToAppend);

    return string.Join(string.Empty, list);
}

The result: List vs Builder

We can see, that the list often can outperform the StringBuilder. And guess what the .NET team uses List<string> instead of a StringBuilder (for example in Blazor).

Conclusion

The world is mostly grey and not black and white. So check for your situation what fits best. Yes, StringBuilder can be faster but also brings more complexity with it. For small amounts, an easy concat will do the trick or you just use a simple List<string>.

Resources

  • Source code to this blog post: here
  • All my sample code is hosted in this repository: here
8
An error has occurred. This application may no longer respond until reloaded. Reload x