Beginner · Arrays, strings and null · topic 12 of 43 · 20 min
StringBuilder and string performance
Explanation
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.
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.
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);Other useful members
| Member | What 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 |
| Length | Number of characters so far (you can set it to shorten) |
| Clear() | Empty it to reuse |
| ToString() | Make the final string |
Comparing the two ways
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); // TrueWhen 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.
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
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.
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());Practice (0/3 done)
Which namespace contains StringBuilder?
What does this print? var sb = new StringBuilder("ab"); sb.Append('c').Insert(0, "x"); Console.WriteLine(sb.ToString());
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- null, nullable types and null-safe operatorsArrays, strings and null · same module
- Arrays: one name, many valuesArrays, strings and null · same module
- StringBuilder and formattingJava Programming (Core to Spring Boot) · Arrays and strings
- Text: C strings and std::stringC++ Programming (modern C++ and DSA) · References, pointers, arrays and strings
- Your first Dart program, variables and typesFlutter and Dart · Dart basics
- Strings: building, comparing and countingData Structures and Algorithms (DSA) for interviews · Arrays and strings
Questions people ask about this
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.
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'.
Which inserts an expression into a string?Related
Answer: 'Total: ${a + b}'
${...} evaluates the expression.
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 more topic in “Arrays, strings and null” before its exam: null, nullable types and null-safe operators.
- Module 3 exam: Arrays, strings and null · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
- 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