@pst - I agree that readability is important, and in most cases it doesnβt matter on a PC, but what if you are on a mobile platform where system resources are limited?
It is important to understand that StringBuilder is the best way for concatenated strings. It is much faster and more efficient.
You emphasized the important difference, however, as to whether it will be significantly faster and in which scenarios. It is significant that the difference should be measured in ticks at low volumes, since it cannot be measured in milliseconds.
It is important to know that for everyday scenarios on the desktop platform, the difference is imperceptible. But itβs also important to know that for mobile platforms, in extreme cases, when you create large strings or execute thousands of concats or to optimize performance, StringBuilder really wins. With a lot of concat, it's worth noting that StringBuilder takes up a bit more memory.
This is by no means an ideal comparison, but for a fool who combines 1,000,000 lines, StringBuilder outperforms regular string concatenation by ~ 10 minutes (on Core 2 Duo E8500 @ 3.16GHz in Win 7 x64):
String concat (10): 9 ticks, 0 ms, 8192 bytes String Builder (10): 2 ticks, 0 ms, 8192 bytes String concat (100): 30 ticks, 0 ms, 16384 bytes String Builder (100): 6 ticks, 0 ms, 8192 bytes String concat (1000): 1658 ticks, 0 ms, 1021964 bytes String Builder (1000): 29 ticks, 0 ms, 8192 bytes String concat (10000): 105451 ticks, 34 ms, 2730396 bytes String Builder (10000): 299 ticks, 0 ms, 40624 bytes String concat (100000): 15908144 ticks, 5157 ms, 200020 bytes String Builder (100000): 2776 ticks, 0 ms, 216888 bytes String concat (1000000): 1847164850 ticks, 598804 ms, 1999804 bytes String Builder (1000000): 27339 ticks, 8 ms, 2011576 bytes
the code:
class Program { static void Main(string[] args) { TestStringCat(10); TestStringBuilder(10); TestStringCat(100); TestStringBuilder(100); TestStringCat(1000); TestStringBuilder(1000); TestStringCat(10000); TestStringBuilder(10000); TestStringCat(100000); TestStringBuilder(100000); TestStringCat(1000000); TestStringBuilder(1000000); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } static void TestStringCat(int iterations) { GC.Collect(); String s = String.Empty; long memory = GC.GetTotalMemory(true); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s += "a"; } sw.Stop(); memory = GC.GetTotalMemory(false) - memory; Console.WriteLine("String concat \t({0}):\t\t{1} ticks,\t{2} ms,\t\t{3} bytes", iterations, sw.ElapsedTicks, sw.ElapsedMilliseconds, memory); } static void TestStringBuilder(int iterations) { GC.Collect(); StringBuilder sb = new StringBuilder(); long memory = GC.GetTotalMemory(true); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { sb.Append("a"); } sw.Stop(); memory = GC.GetTotalMemory(false) - memory; Console.WriteLine("String Builder \t({0}):\t\t{1} ticks,\t{2} ms,\t\t{3} bytes", iterations, sw.ElapsedTicks, sw.ElapsedMilliseconds, memory); } }