TheDeveloperBlog.com


C# StringBuilder Performance

StringBuilder is an optimization. But it doesn't always improve performance. We determine the point at which StringBuilder becomes faster. Here we see benchmarks of StringBuilder and strings. We discuss the important considerations.


Benchmark. To start, we see the code styles that were benchmarked to produce the graph. This is an adjunct article to my other StringBuilder work. What was tested here were tight loops that append a single string each iteration.

Info: The number of strings that were appended was steadily increased to determine the slope of the graph.

StringBuilder default code, red line: C#

StringBuilder builder1 = new StringBuilder();
for (int i = 1; i < count1; i++)
{
    builder1.Append(s);
}
return builder1.ToString();

StringBuilder with capacity, purple line: C#

StringBuilder builder2 = new StringBuilder(count1 * maxLength);
for (int i = 1; i < count1; i++)
{
    builder2.Append(s);
}
return builder2.ToString();

String concat, blue line: C#

string st1 = string.Empty;
for (int i = 1; i < count1; i++)
{
    st1 += s;
}
return st1;

My test tried to defeat every compiler optimization by using different strings of the same lengths to append. The tests were repeated 20 times more for counts below 8 strings. You can see the graph above.

The benchmark indicates that using the string reference type with Concat is faster for one to four strings inclusive. Using StringBuilder with an accurate capacity is always faster than without.


Discussion. Here we look at what I think the best way to use StringBuilder is. Use StringBuilder always when you have a loop of a variable length. This will make your program usable in more scenarios than string Concat will.

string.Concat

For example, if a program has three strings 99% of the time, but 30,000 strings 1% of the time, StringBuilder will make the program usable in that 1%. An important part of good programming is planning for errors and edge cases.

Warning: If your program is lightning fast 99% of the time, but fails 1% of the time, your program is unacceptable for important work.

Therefore: I think StringBuilder is preferable in most loops, unless you have studied the input to the loop.


Problems. There are many problems to this test. The individual strings themselves were 20 characters long. This may not match many programs in the real world. I benchmarked no cases where there are hundreds of thousands of strings.

But: It is clear to me that the trend of the lines would continue. I used capacity settings that were 100% accurate.

Capacity

Summary. StringBuilder is entirely an optimization. It offers no logical improvements to string Concat other than its internal implementation. It is sometimes fine to use small loops (of four or fewer iterations) with simple string concatenations.

Optimizations

Note: In edge cases, using string concats can be disastrous. Plan for your edge cases with StringBuilder.