Use StringBuilder to create string from a large number of records

public string GetCustomerNamesCsv()
    List<CustomerData> customerDataRecords = GetCustomerData(); // Returns a large number of records, say, 10000+

    StringBuilder customerNamesCsv = new StringBuilder();
    foreach (CustomerData record in customerDataRecords)

    return customerNamesCsv.ToString();

What a StringBuilder is and when to use one

A StringBuilder represents a series of characters, which unlike a normal string, are mutable. Often times there is a need to modify strings that we've already made, but the standard string object is not mutable. This means that each time a string is modified, a new string object needs to be created, copied to, and then reassigned.

string myString = "Apples";
mystring += " are my favorite fruit";

In the above example, myString initially only has the value "Apples". However, when we concatenate `" are my favorite fruit"', what the string class does internally needs to do involves:

  • Creating a new array of characters equal to the length of myString and the new string we are appending.
  • Copying all of the characters of myString into the beginning of our new array and copying the new string into the end of the array.
  • Create a new string object in memory and reassign it to myString.

For a single concatenation, this is relatively trivial. However, what if needed to perform many append operations, say, in a loop?

String myString = "";
for (int i = 0; i < 10000; i++)
    myString += " "; // puts 10,000 spaces into our string

Due to the repeated copying and object creation, this will bring significantly degrade the performance of our program. We can avoid this by instead using a StringBuilder.

StringBuilder myStringBuilder = new StringBuilder();    
for (int i = 0; i < 10000; i++)
    myStringBuilder.Append(' ');

Now when the same loop is run, the performance and speed of the execution time of the program will be significantly faster than using a normal string. To make the StringBuilder back into a normal string, we can simply call the ToString() method of StringBuilder.

However, this isn't the only optimization StringBuilder has. In order to further optimize functions, we can take advantage of other properties that help improve performance.

StringBuilder sb = new StringBuilder(10000); // initializes the capacity to 10000

If we know in advance how long our StringBuilder needs to be, we can specify its size ahead of time, which will prevent it from needing to resize the character array it has internally.

sb.Append('k', 2000);

Though using StringBuilder for appending is much faster than a string, it can run even faster if you only need to add a single character many times.

Once you have completed building your string, you may use the ToString() method on the StringBuilder to convert it to a basic string. This is often necessary because the StringBuilder class does not inherit from string.

For example, here is how you can use a StringBuilder to create a string:

string RepeatCharacterTimes(char character, int times)
    StringBuilder builder = new StringBuilder("");
    for (int counter = 0; counter < times; counter++)
        //Append one instance of the character to the StringBuilder.
    //Convert the result to string and return it.
    return builder.ToString();

In conclusion, StringBuilder should be used in place of string when many modifications to a string need to be made with performance in mind.