Skip to content

Beginner · Arrays, strings and null · topic 12 of 43 · 20 min

StringBuilder and string performance

Explanation

Because strings are immutable, adding to a string inside a long loop creates a new string every time, which wastes time and memory. StringBuilder keeps one growing buffer that you Append to, and you call ToString() once at the end. Use it when you build text in a loop; for a few joins, plain + or interpolation is fine.

The hidden cost of +=

When you write report += line; C# cannot change the old string. It creates a brand-new string, copies all the old characters into it, adds the new ones, and throws the old string away for the garbage collector. In a loop of 10,000 lines, the copying grows and grows: line 10,000 copies everything from the 9,999 lines before it.

Think of it like this: Using += in a loop is like rewriting your whole notebook page by hand every time you want to add one sentence. StringBuilder is like a notebook with blank pages: you just keep writing at the end, and photocopy the finished notebook once.

StringBuilder basics

StringBuilder lives in the System.Text namespace, which is not in the default implicit usings, so add using System.Text; at the top of the file.

csharp
using System.Text;

var sb = new StringBuilder();
sb.Append("Invoice #");
sb.Append(2041);
sb.AppendLine();                 // adds a new line
sb.AppendLine("Item     Qty  Price");
sb.AppendLine($"{"Pen",-8} {2,3} {20.00m,6:F2}");
string result = sb.ToString();
Console.WriteLine(result);
Append adds text (or numbers) to the end. AppendLine adds text and then a new line. ToString gives the finished string.

Other useful members

MemberWhat it does
Append(x)Add x to the end
AppendLine(x)Add x and a new line
Insert(index, x)Insert x at a position
Replace(a, b)Replace text inside the builder
Remove(start, length)Delete characters
LengthNumber of characters so far (you can set it to shorten)
Clear()Empty it to reuse
ToString()Make the final string

Comparing the two ways

csharp
using System.Diagnostics;
using System.Text;

var watch = Stopwatch.StartNew();
string s = "";
for (int i = 0; i < 20_000; i++) s += i + ",";
Console.WriteLine($"+= took {watch.ElapsedMilliseconds} ms");

watch.Restart();
var sb = new StringBuilder();
for (int i = 0; i < 20_000; i++) sb.Append(i).Append(',');
string t = sb.ToString();
Console.WriteLine($"StringBuilder took {watch.ElapsedMilliseconds} ms");
Console.WriteLine(s == t);   // True
Run it yourself: the exact times depend on your computer, but StringBuilder is usually many times faster for big loops.

When NOT to use StringBuilder

  • Joining two to five pieces once: $"{first} {last}" is clearer and just as fast.
  • Joining all items of an array or list with a separator: string.Join(", ", items) is simpler.
  • Very short loops (a handful of rounds): the difference is too small to matter; choose what reads better.
Tip: Rule of thumb: building text inside a loop that could run hundreds of times or more? Use StringBuilder. Otherwise use interpolation or string.Join.

Common mistakes and fixes

  • Forgetting using System.Text;: error CS0246, the type StringBuilder could not be found.
  • Printing the builder instead of calling ToString(): Console.WriteLine(sb) actually works (it calls ToString for you), but passing sb where a string is expected does not compile. Call sb.ToString().
  • Calling ToString() inside the loop: that makes a new string each time, which undoes the benefit. Call it once at the end.
  • Measuring speed in a Debug build with one tiny run: measure bigger loops, ideally in a Release build (dotnet run -c Release).

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

StringBuilder and string performance · 1/6

StringBuilder

In this lesson you will learn why adding to a string in a long loop is slow, and how StringBuilder fixes it.

Prefer a video by a teacher? Find free videos on “C# StringBuilder vs string concatenation performance” on YouTube ↗

In real life: Generating a CSV of the day's orders

A small online store in Surat exports the day's orders to a CSV file for its accountant. The orders can number in the thousands during a sale, so the export builds the file with StringBuilder.

csharp
using System.Text;

string[] customers = { "Asha", "Ravi", "Meena" };
decimal[] totals = { 499m, 1299.5m, 250m };

var csv = new StringBuilder();
csv.AppendLine("OrderNo,Customer,Total");
for (int i = 0; i < customers.Length; i++)
{
    csv.Append(1001 + i).Append(',')
       .Append(customers[i]).Append(',')
       .AppendLine(totals[i].ToString("F2"));
}
Console.Write(csv.ToString());
Append returns the same builder, so calls can be chained. Real CSV code must also handle commas and quotes inside names.

Practice (0/3 done)

Task 1 · Question

Which namespace contains StringBuilder?

Task 2 · Question

What does this print? var sb = new StringBuilder("ab"); sb.Append('c').Insert(0, "x"); Console.WriteLine(sb.ToString());

Task 3 · Practice

Write a method MultiplicationTable(int n) that returns (not prints) the table of n from 1 to 10 as one string, one line per row like "7 x 3 = 21". Use StringBuilder and call ToString once.

Quick quiz

Question 1

1.Why is s += x slow inside a big loop?

Question 2

2.When is plain interpolation better than StringBuilder?

Question 3

3.What gives you the final string from a StringBuilder sb?

Question 4

4.Best way to join a string[] names with ", " between them?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Why is s += x slow inside a big loop?

Answer: Each += creates a new string and copies all old characters

Immutability means a new string and a full copy every time.

When is plain interpolation better than StringBuilder?

Answer: When joining a few pieces once

For a few pieces, interpolation is clearer and fast enough.

What gives you the final string from a StringBuilder sb?

Answer: sb.ToString()

ToString() creates the finished string.

Best way to join a string[] names with ", " between them?

Answer: string.Join(", ", names)

string.Join is made for exactly this.

Why use StringBuilder in a loop?Related

Answer: It avoids creating a new String object on every iteration

StringBuilder is mutable.

From StringBuilder and formatting

What does immutable mean for strings?Related

Answer: Once made, a string's characters cannot change; methods return new strings

Every "change" creates a new string.

From Strings: methods, interpolation, verbatim and raw strings

What marks the end of a C string?Related

Answer: The null character '\0'

C functions read characters until they meet '\0'.

From Text: C strings and std::string

Which inserts an expression into a string?Related

Answer: 'Total: ${a + b}'

${...} evaluates the expression.

From Your first Dart program, variables and types

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Arrays, strings and null” before its exam: null, nullable types and null-safe operators.
  2. Module 3 exam: Arrays, strings and null · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Classes and objects. 43 topics left in the course before the final exam.

← Previous: Strings: methods, interpolation, verbatim and raw strings