Friday, 31 May 2013

StringBuilder vs String


In this post, we'll discuss the pros and cons of using the StringBuilder functionality over String, and vice versa.

We’ll go about what Immutability is, how run-time strings differ from compile-time ones, memory allocation for String & StringBuilder, and finally wrap up with the difference between Lists holding Immutable Reference Types & Lists holding Mutable Reference Types.


In the beginning of the video series, we go through the basics of Mutability & Immutability and what its effects are on the Garbage Collector. As a StringBuilder is mutable & a character array, it has an edge over String when it comes to Concatenation. The Append functionality is the key highlight here.

We next see how the StringBuilder maintains its buffer and Resizes to allocate NEW memory only when it reaches its extendable limit. Of course, the upper limit is a limited number (2^32 capacity) unlike in String (Goes on until we hit a SystemOutOfMemory Exception).

We wrap up with a demonstration on how a List<string> holds values and how a List<StringBuilder> holds values. Also, the functionality of Clear() and “new” is slightly different for StringBuilder, unlike the equivalent functionalities in String. These facts matter because it highlights the style of Memory allocation.

For a deeper understanding on all that has been mentioned above, please check out the 5 video links where I go through the demo in full detail.


C# Experiments: StringBuilder vs String (Part 1)


 C# Experiments: StringBuilder vs String (Part 2)



C# Experiments: StringBuilder vs String (Part 3)



C# Experiments: StringBuilder vs String (Part 4)



C# Experiments: StringBuilder vs String (Part 5)



C# Experiments: StringBuilder vs String (Part 6)



The code typed-in during the tutorial-session is as follows:-


    //A String is Immutable [It cannot be "changed".]
    //A StringBuilder can be "changed" any number of times. <-- Mutable sequence of characters.

    //Mutable => Modificable by Appending, Removing, Replacing characters, etc.

    string str1 = "hi";
    str1 = str1.Replace(str1, "hello");

    MessageBox.Show(str1);

    StringBuilder sb1 = new StringBuilder("bye");
    sb1.Replace(sb1.ToString(), "goodbye");
    MessageBox.Show(sb1.ToString());

    //A StringBuilder is char[]
    //Both String & StringBuilder are stored in the heap.

    //Compile-Time Strings are Concatenated without the NEW memory allocations.

    //string str2 = "ab" + "cd" + "ef"; //ONLY ONE STRING during Run-Time.
    //abcdef

    //A Run-Time string concatenation operation ALWAYS allocates NEW memory.

    //Created 40002 Strings. Wasted away 40000 of them.
    string str2 = string.Empty;

    Stopwatch s1 = Stopwatch.StartNew();
    for (int i = 0; i < 20000; i++)
        str2 = str2 + i.ToString() + " ";

    s1.Stop();
    MessageBox.Show(s1.ElapsedMilliseconds.ToString());

    // A StringBuilder maintains a buffer to accomodate the concatenations of new data.
    //[Append Feature]

    //A stringbuilder concatenation operation allocates NEW memory  ONLY if the object buffer needs to be RESIZED.

    //A StringBuilder has a max capacity of 2^32

    Stopwatch s2 = Stopwatch.StartNew();
    StringBuilder sb2 = new StringBuilder();

    for (int i = 0; i < 200000; i++)
    {
        //sb2.Append(i);
        //sb2.Append(" ");

        //Chaining Functionality.
        //sb2.Append(i).Append(" ");

        sb2.Append(i + " ");
    }

    s2.Stop();
    MessageBox.Show(s2.ElapsedMilliseconds.ToString());

    //List holds Immutable Reference Types
    var stringList = new List<string>();

    //List holds Mutable Reference Types
    var sbList = new List<StringBuilder>();

    var pureStringList = new List<string>();
    string sample = "";

    var sb = new StringBuilder();
    int j = 0;

    for (int i = 0; i < 5; i++)
    {
        for (int k = 0; k < 5; k++)
        {
            sample += j.ToString();
            sb.Append(j++);
        }

        sbList.Add(sb);
        stringList.Add(sb.ToString());
        pureStringList.Add(sample);

        //With Clear Functionality
        sb.Clear();
        sample = "";

        //With New Functionality
        //sb = new StringBuilder();

    }


Thank you for reading this post and watching the videos. Please Subscribe, Comment, and Rate the channel if you liked the videos.

Goto C# Experiments to access more of such content! Thanks again!