Are StringBuilders always faster than concatenation?
So just in case you don't know, here's what's wrong with concatenating a lot of strings using the + operator (& for our VB friends)... A string is an immutable object, which means that every time you change it, the old string object gets thrown away and a new one is created, which means allocating new memory. So if you repeatedly concatenate a large number of strings, the memory you're going to spend on that is going to grow roughly with the square of the number of strings.
A StringBuilder, on the other hand, just keeps references to all the string bits, and only really concatenates when you call ToString(). Everything stays nicely linear and you can safely concatenate several millions of strings with reasonable performance (not that it's a good idea, but you can).
Now, it doesn't mean that you should use StringBuilder all the time. For example, a common piece of code that you write in ASP.NET is constructing a client-side script string dynamically from static and dynamic bits (typically, a control's ClientID can be injected in some script that uses the client-side HTML structure rendered by the control). There are three approches you can take to that.
The first one, probably the easiest to write and to read is to use String.Format. Unfortunately, it performs poorly. Use it if readability is more important to you than performance.
The second one is to use StringBuilder, and the third one is to use string concatenation.
The crucial point here is that in the script generation case, we know in advance how many string bits we want to concatenate, which is very different from concatenating an arbitrary number of strings in a loop. Let's look at the last two approaches in details, as simplified in this sample code:
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
for (int c = 0; c < 5000000; c++) {
int i = 0;
string a = "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a";
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
for (int c = 0; c < 5000000; c++) {
int i = 0;
StringBuilder sb = new StringBuilder(15);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
string a = sb.ToString();
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
newarr [mscorlib]System.Object
... lots of array initialization code...
call string [mscorlib]System.String::Concat(object[])