How to prove you are a novice .NET programmer (String Concatenations)

I freely admit that I still have a lot to learn with respect to .NET programming.  I figure in any endeavor the day you think you have finally figured it all out is the day when you have well and truly, totally deluded yourself.  There are many ways to determine that somebody (yourself or another) is a novice .NET programmer, but there are some things that truly seem to stand out for me.

String Concatenation

How string concatenations are coded has implications on raw code performance but far more importantly it has a HUGE impact on memory performance.  When the string concatenations are occurring within a web application they could cause recycling of the application pool.  Basically, with reference to memory performance, the more temporary objects code creates that need to be garbage collected the more often garbage collections have to occur and the more likely that the code could receive OutOfMemoryExceptions and/or the application performance suffer during the garbage collections.

There are basically two methods for concatenating strings in C#.  Use of the overloaded string concatenation operator ‘+’ and use of the StringBuilder class.  There are a variety of BCL class methods that concatenate strings like string.Join, but underneath they are usually using the StringBuilder class so I’ll ignore that permutation of this issue.

There is a good article at documenting the raw code performance statistics in some sample code between the two methods of string concatenation.  The code sample used uses a loop to concatenate a string 5,000 times.  You might think this is an extreme example used to illustrate the issue.  It would be nice to think so, however I recently saw some code that used 40+ concatenations per record to generate a string for a data structure that consisted of approximately 20,000 records.  That comes to over 800,000 string concatenations.  Ok, forget the extreme examples, let’s look at the following code:

    data = "\"" + data + "\",";

Each time this line of code executes it will create two new strings and leaves two old strings around to be garbage collected at some point in the future.  Now do this in a loop 10 times or 20 times or 100 times.

  • String 1 = "\"" + data
  • String 2 = (String 1) + "\","
  • Throw away String 1
  • Throw away the original value of data
  • Keep String 2 (at least until the next concatenation occurs)

On the other hand the code:

    data = string.Format("\"{0}\",", data);

creates one new string and leaves the old value of data to be garbage collected at some point in the future.  Using the StringBuilder class does even better with the code:

    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.AppendFormat("\"{0}\",", data);

which doesn’t create any new strings (until the point that all concatenations are complete and a call is made to stringBuilder.ToString()) and leaves the old value of data to be garbage collected at some point in the future. There are some considerations when using the StringBuilder class in needing to use the StringBuilder(int) constructor overload to give StringBuilder a larger than default estimate on how big the string will get to reduce the amount of internal array allocations that are used to hold the parts of the once and future string.

Let’s look a little bit more at some more code that appears fairly regularly:

    string result = String.Empty;
    foreach (var item in items)
        if (!String.IsNullOrEmpty(result))
            result += ",";
        result += item.Name;

    return result;

If this code executes on a collection with just four values it will have created eight new strings, returning one and leaving 7 to be garbage collected.  This code could be rewritten in a couple of different ways:


    StringBuilder result = new StringBuilder();
    foreach(var item in items)
        if (result.Length > 0)

    return result.ToString();

But why even have all that code? I love LINQ! And string.Join uses the StringBuilder class for us.


    return string.Join(",", items.Select(item => item.Name));