String vs. StringBuilder

Yes, the performance difference is significant. See the KB article "How to improve string concatenation performance in Visual C#".

I have always tried to code for clarity first, and then optimize for performance later. That's much easier than doing it the other way around! However, having seen the enormous performance difference in my applications between the two, I now think about it a little more carefully.

Luckily, it's relatively straightforward to run performance analysis on your code to see where you're spending the time, and then to modify it to use StringBuilder where needed.


To clarify what Gillian said about 4 string, if you have something like this:

string a,b,c,d;
 a = b + c + d;

then it would be faster using strings and the plus operator. This is because (like Java, as Eric points out), it internally uses StringBuilder automatically (Actually, it uses a primitive that StringBuilder also uses)

However, if what you are doing is closer to:

string a,b,c,d;
 a = a + b;
 a = a + c;
 a = a + d;

Then you need to explicitly use a StringBuilder. .Net doesn't automatically create a StringBuilder here, because it would be pointless. At the end of each line, "a" has to be an (immutable) string, so it would have to create and dispose a StringBuilder on each line. For speed, you'd need to use the same StringBuilder until you're done building:

string a,b,c,d;
StringBuilder e = new StringBuilder();
 e.Append(b);
 e.Append(c);
 e.Append(d);
 a = e.ToString();

StringBuilder is preferable IF you are doing multiple loops, or forks in your code pass... however, for PURE performance, if you can get away with a SINGLE string declaration, then that is much more performant.

For example:

string myString = "Some stuff" + var1 + " more stuff"
                  + var2 + " other stuff" .... etc... etc...;

is more performant than

StringBuilder sb = new StringBuilder();
sb.Append("Some Stuff");
sb.Append(var1);
sb.Append(" more stuff");
sb.Append(var2);
sb.Append("other stuff");
// etc.. etc.. etc..

In this case, StringBuild could be considered more maintainable, but is not more performant than the single string declaration.

9 times out of 10 though... use the string builder.

On a side note: string + var is also more performant that the string.Format approach (generally) that uses a StringBuilder internally (when in doubt... check reflector!)


A simple example to demonstrate the difference in speed when using String concatenation vs StringBuilder:

System.Diagnostics.Stopwatch time = new Stopwatch();
string test = string.Empty;
time.Start();
for (int i = 0; i < 100000; i++)
{
    test += i;
}
time.Stop();
System.Console.WriteLine("Using String concatenation: " + time.ElapsedMilliseconds + " milliseconds");

Result:

Using String concatenation: 15423 milliseconds

StringBuilder test1 = new StringBuilder();
time.Reset();
time.Start();
for (int i = 0; i < 100000; i++)
{
    test1.Append(i);
}
time.Stop();
System.Console.WriteLine("Using StringBuilder: " + time.ElapsedMilliseconds + " milliseconds");

Result:

Using StringBuilder: 10 milliseconds

As a result, the first iteration took 15423 ms while the second iteration using StringBuilder took 10 ms.

It looks to me that using StringBuilder is faster, a lot faster.


This benchmark shows that regular concatenation is faster when combining 3 or fewer strings.

http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/

StringBuilder can make a very significant improvement in memory usage, especially in your case of adding 500 strings together.

Consider the following example:

string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
    buffer += i.ToString();
}
return buffer;

What happens in memory? The following strings are created:

1 - "The numbers are: "
2 - "0"
3 - "The numbers are: 0"
4 - "1"
5 - "The numbers are: 01"
6 - "2"
7 - "The numbers are: 012"
8 - "3"
9 - "The numbers are: 0123"
10 - "4"
11 - "The numbers are: 01234"
12 - "5"
13 - "The numbers are: 012345"

By adding those five numbers to the end of the string we created 13 string objects! And 12 of them were useless! Wow!

StringBuilder fixes this problem. It is not a "mutable string" as we often hear (all strings in .NET are immutable). It works by keeping an internal buffer, an array of char. Calling Append() or AppendLine() adds the string to the empty space at the end of the char array; if the array is too small, it creates a new, larger array, and copies the buffer there. So in the example above, StringBuilder might only need a single array to contain all 5 additions to the string-- depending on the size of its buffer. You can tell StringBuilder how big its buffer should be in the constructor.