String versus StringBuilder

String versus StringBuilder and what some of the pros and cons are to each. To start off we need to understand what immutable means and what mutable means.  Immutable in basic terms means the original object cannot be altered.  An attempt to alter or concatenate to an existing object will result in a new object being created each time.  A mutable object means that you can add to the existing object without a new one being created.

A String is an immutable object.  So every time that we change a string, a new string is actually getting created.  This is not the most efficient use of memory if you are doing multiple concatenations to a string, you will be creating a new string object each time. This whole discussion of immutability is a deep subject for another post.

So let’s take a look at this loop for if you have a 100,000 iterations of adding a sentence to a string. This is just adding a sentence to the string each time, however because its an immutable object it is creating a new string object each time.  This has memory efficiency issues as well as it can slow down performance when you get large strings and many iterations of adding them together.

private static string LoopResult(string result)
{
    for (int i = 0; i < 10000; i++)
    {
        result += "Lets just concat a sentence on the end of it each time.";
    }
    return result;
}

So what I did was created a simple test method using a Stopwatch and benchmarked 5 runs of this method as follows.

public void IterationTest()
{
    string result = "";

    Stopwatch sw = new Stopwatch();
    sw.Start();
    result = LoopResultConcat(result);
    sw.Stop();

    long elapsedTicks = sw.ElapsedTicks;
}

After 5 test runs these were the outcomes in Ticks.

Using string +=
Test 1 = 20234811
Test 2 = 19659463
Test 3 = 20091368
Test 4 = 19763153
Test 5 = 19698219

Going through the test it didn’t seem to bad considering how many characters and iterations were being taken into account.  However, lets switch it up and use a StringBuilder and do a .append() on the end string during the loop. That looks like this.

private string LoopResult(string result, StringBuilder sb)
{
    for (int i = 0; i < 10000; i++)
    {
        sb.Append("Lets just concat a sentence on the end of it each time.");
    }
    return sb.ToString();
}

This proved to have a substantial gain over the string += method. The results listed below show that using the .Append() method substantially increases the processing time of building the extremely long string.

Using StringBuilder.Append()
Test 1 = 11198
Test 2 = 15684
Test 3 = 12751
Test 4 = 12646
Test 5 = 11763

As a side note, in our main IterationTest() method we will instantiate our new StringBuilder object with a designated capacity.  The StringBuilder object gets allocated a specific capacity, 16 characters when its instantiated; then it gets re-allocated each time it reaches its limit.  That is why we set the capacity we will need upfront so that it will not have to be re-allocated at all in the process.

StringBuilder sb = new StringBuilder(550080);

These are some of the many things to consider when dealing with rather large strings and the concatenating of strings. Overall, we can see that StringBuilder is a lot more performance conscious as well as it will leave less for the garbage collector to clean up in the process.


Leave a Reply

Your email address will not be published. Required fields are marked *

StackOverflow Profile