String concatenation discovery – not the usual += bit – level 300

We’ve all seen the demo where Stringbuilder blows away appending strings in a
loop where you just do a += or string = string + something.

 

I’m not going to cover that scenario, but I did compare 4 different “fast”
ways to concatenate strings, and one of them blows away stringbuilder by a big
margin  Here’s the test code:

            int numIterations = 10000000;

 

            DateTime startDate, endDate;

            string result = string.Empty;

            string h;

            h = “h”;

 

            startDate = DateTime.Now;

            for(int i = 0; i < numIterations; i++)
{

                result = “h”

                    + “a”

                    + “b”

                    + “c”

                    + “d”

                    + “e”

                    + “f”

                    + “g”

                    + “h”

                    + “i”

                    + “j”

                    + “k”;

            }

            endDate = DateTime.Now;

            Console.WriteLine(“All literal concat
12: ” + endDate.Subtract(startDate));

 

            startDate = DateTime.Now;

            for(int i = 0; i < numIterations; i++)
{

                result = “h”

                    + “h”

                    + h

                    + “h”

                    + h

                    + “h”

                    + h

                    + “h”

                    + h

                    + “h”

                    + h

                    + “h”;

            }

            endDate = DateTime.Now;

            Console.WriteLine(“+ 12: ” +
endDate.Subtract(startDate));

 

            startDate = DateTime.Now;

            for(int i = 0; i < numIterations; i++)
{

                string.Concat(“h”, “h”, “h”, “h”, “h”, “h”,
“h”, “h”, “h”, “h”, “h”, “h”);

            }

            endDate = DateTime.Now;

            Console.WriteLine(“String.Concat 12: ”
+ endDate.Subtract(startDate));

 

            startDate = DateTime.Now;

            for(int i = 0; i < numIterations; i++)
{

                StringBuilder x = new StringBuilder();

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.Append(“h”);

                x.ToString();

            }

            endDate = DateTime.Now;

            Console.WriteLine(“StringBuilder 12: ”
+ endDate.Subtract(startDate));

 

 

            Console.ReadLine();

 

Here we have 4 scenarios, and here is the console results:

All literal concat 12: 00:00:00.0400648
+ 12:
00:00:06.0497848
String.Concat 12: 00:00:06.4804814
StringBuilder 12:
00:00:06.2100440

 

I have other programs running, so my results aren’t laboratory-clean, BUT,
notice the first result.  The first method took only 4/100th of a second where
the other three were pretty close at 6 seconds.  These results are x 10 million
to get measurable results.  So I can only conclude that the C# or MSIL compiler
has some special optimization for situations where the strings I’m concatenating
are all literals and not a mixture of literals and string variables.

Very interesting, indeed.  What I understand from this test is that if I have
all my strings ready to go, using the good ol’ +…+….+….+…. works the
fastest and should NOT be replaced with StringBuilder.  Wow.  I learn something
new every day.

Update:  Wesner had some great feedback:

When you are concatenating just literals, then the compiler performs the
concatenation at compile-time instead of run-time.

result = “h” + “a” +
“b” + “c” + “d” + “e” + “f” + “g” + “h” + “i” + “j” + “k”;

is optimized
to

result = “habcdefghijk”;

This explains why the first case was the fastest.