In C# strings are immutable , so string + string creates a new string. This means coping both strings into the new result string. That is a lot of copying and can be pretty slow if you do it on large strings, or often on small strings. Especially if you concatenate multiple strings at once (A + B + C + D means that A is copied 3 times, B 3 times, C twice, and D once) StringBuilder is mutable so appends don't recopy data. It is really only a problem if you do it on large strings more than a few times.
On the other hand I am not sure if this is a problem in .NET. I know the semantics look bad but no one said the execution model had to match the semantics. If I remember correctly the JVM has the capability to rewrite the code to the faster version, though I am not sure if the CLR does.
The JVM does rewrite individual concatenations as StringBuilders (so a+b+c+d results in one StringBuilder with three .append() operations), but the real performance problem is concatenating in a loop.
String result = "";
for (String str : myStrings) {
result += str + " "; // on each execution, a new StringBuilder is created
}
as opposed to
StringBuilder result = new StringBuilder();
for (String str : myStrings) {
result.append(str).append(" ");
}
The JVM can't hoist the generated StringBuilder out of loops to produce the second, faster piece of code. I believe the CLR is the same.
At least in Oracle Java 1.6 update 24, which is supposed to have escape analysis enabled by default, it is a huge difference. I don't know if Java 7's analysis is smarter.
On the other hand I am not sure if this is a problem in .NET. I know the semantics look bad but no one said the execution model had to match the semantics. If I remember correctly the JVM has the capability to rewrite the code to the faster version, though I am not sure if the CLR does.