csharp-stringbuilder

What is and how to use StringBuilder in C#

  • 2 min

In the first article about Strings, we said that they are immutable and that modifying them creates a new String (with the associated speed and memory consumption problems).

*But what happens if I have to join 10,000 words?

If you use a normal String, your program will suffer. This is where performance comes into play: the StringBuilder.

The Problem of Concatenation

Imagine this scenario:

string texto = "";
for (int i = 0; i < 10000; i++)
{
    texto += i.ToString(); // !!PERFORMANCE ERROR!! // 
}

Copied!

On each loop iteration, C# has to:

  1. Copy the old string.
  2. Add the new character.
  3. Create a new object.
  4. Discard the old one.

Very efficient, doesn’t it seem true? No, it’s not.

The Solution: System.Text.StringBuilder

StringBuilder is a class designed to be mutable. That is, a String that can change.

It works internally with a dynamic array of characters that has extra capacity (a buffer). When you add text, it simply fills the empty spaces in that array. It doesn’t create new objects.

If the array gets full, StringBuilder creates a new one (usually twice as large), copies the data, and continues. This happens very few times compared to normal concatenation.

This is the maximum possible optimization in text manipulation.

Don’t go crazy changing all your string to StringBuilder. StringBuilder has an initialization cost and lacks the safety of immutability.

  1. If you are going to concatenate 3 or 4 things, use string + string or interpolation $"{a}{b}". It’s faster and more readable.
  2. If you are going to concatenate inside a loop hundreds or thousands of times, use StringBuilder.

How to Use StringBuilder

StringBuilder is located in the System.Text namespace.

using System.Text;

StringBuilder sb = new StringBuilder();

sb.Append("Hello");
sb.Append(" ");
sb.AppendLine("World"); // Adds and line breaks
sb.AppendFormat("The value is {0}", 100);

// Finally, we convert to an immutable String
string resultado = sb.ToString();

Copied!

Some of its main methods are:

  • Append(): Adds to the end.
  • AppendLine(): Adds to the end with a line break.
  • Insert(index, value): Inserts at a position (more costly, has to move elements).
  • Remove(index, length): Deletes a part.
  • Clear(): Clears the content to reuse the instance.

Capacity Optimization

If you know in advance (or roughly) how long your final text will be, you can pass it to the constructor to avoid it having to resize the internal array.

// Creates an initial buffer of 1000 characters
StringBuilder sb = new StringBuilder(1000); 
Copied!