Optimising StringBuilder Appending

I have been working on some C# code optimisation, for speed.  The code in question does a lot of work with strings, so we already use StringBuilder to make it more efficient.  But what is the fastest way to append stuff to the StringBuilder?  In this instance, we're building a lot of comma seperated lists, and even with StringBuilder there are several ways, for example:

 

Method 1, AppendFormat:

sb.AppendFormat("{0},",myStr);

 

Method 2, Multiple Append:

sb.Append(myStr);

sb.Append(",");

 

Method 3, Multiple Append (with a comma already in a string):

string sep = ",";

...

sb.Append(myStr);

sb.Append(sep);

 

Method 4, Single Append:

sb.Append(myStr+sep);

 

... so I decided to check it out.  Here are the results (in seconds), after using each technique one hundred million times (I did five tests and then averaged the results):

 

 

#1

#2

#3

#4

#5

Average

1 AppendFormat

17.20

17.56

17.36

17.58

17.55

17.45

2 Multiple Append

6.61

7.27

6.70

7.27

7.28

7.03

3 Multiple Append (comma in string)

6.65

7.20

6.75

7.20

7.20

7.00

4 Single Append

8.13

8.34

8.31

8.34

8.34

8.29

 

I was quite surprised at how much slower AppendFormat was (although I can understand why).  But it's also worth remembering that the lazy coders way of using a single Append with the + operator to attach the comma is quite a bit slower than calling two Append methods (again, you can understand why when you think about it).

 

Here is the code that I used to test:

 

static void Main(string[] args)

{

    DateTime start = DateTime.Now;

    StringBuilder sb = new StringBuilder();

    string myStr = "hi";

 

    for (int t = 0; t < 100000000; t++)

    {

        sb.AppendFormat("{0},",myStr);

        if ((t % 1000)==0) sb.Remove(0, sb.Length - 1); 

    }

    TimeSpan gap = DateTime.Now - start;

    Console.WriteLine("AppendFormat takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr);

        sb.Append(",");

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Multiple Appends takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    string sep = ",";

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr);

        sb.Append(sep);

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Multiple Appends (comma in string) takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr+sep);

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Single Append (comma in string) takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    Console.ReadKey(); 

}