Tuesday, November 13, 2007

String Concatenation versus StringBuilder Class

When concatenating large strings (for example, building an HTML table from a database),the length of time to complete can become quite long as the string gets larger. This article demonstrates the difference in string concatenation using String and StringBuilder classes.

String Concatenation using String Class.

An ordinary code to create a string from a subset of two strings is usually implemented this way:

string c = "sample" + "code";

This approach usually does the job for most of the applications that we write. But when the situation comes that we need to create a large subset of string by continuous iteration (e.g. a string that contains all numbers from 0 to 10000 or as mentioned above, building an HTML table from database, this approached was proven to be inefficient. According to the Microsoft KB Article # 170964, here's what really happens when we concatentate two strings:

  1. Allocates temporary memory large enough to hold the result.
  2. Copies Destination to the start of the temporary area.
  3. Copies Source to the end of the temporary area.
  4. De-allocates the old copy of Destination.
  5. Allocates memory for Destination large enough to hold the result.
  6. Copies the temporary data to Destination.

Steps 2 and 6 are very expensive and basically result in the entire concatenated result being copied twice with additional overhead to allocate and de-allocate memory. A typical 100K iterations using this string processing will take more or less four minutes to complete.

String Concatenation using StringBuilder Class.

The performance of a concatenation operation for a String or StringBuilder object depends on how often a memory allocation occurs. A String concatenation operation always allocates memory, whereas a StringBuilder concatenation operation only allocates memory if the StringBuilder object buffer is too small to accommodate the new data. Consequently, the String class is preferable for a concatenation operation if a fixed number of String objects are concatenated. In that case, the individual concatenation operations might even be combined into a single operation by the compiler. A StringBuilder object is preferable for a concatenation operation if an arbitrary number of strings are concatenated; for example, if a loop concatenates a random number of strings of user input.

Here's a sample code that I wrote to demostrate the comparison:



using System;
using
System.Web;
using
System.Text;
public
partial class _Default : System.Web.UI.Page
{
string myString = "";
StringBuilder sb = new StringBuilder();
protected void
Page_Load(object sender, EventArgs e)
{
Response.Write(
"Start 100K loops
using string catenation:"
+
DateTime.Now.ToString(
"HH:mm:ss:ff")+"<br/>");
Iterate100K_With_StringAppend();
Response.Write("End 100K loops using string catenation :" +
DateTime.Now.ToString
"HH:mm:ss:ff") + "<br/>");
Response.Write("Start 100K loops using StringBuilder: " +
DateTime.Now.ToString(
"HH:mm:ss:ff") + "<br/>");
Iterate100K_With_StringBuilder();
Response.Write("End 100K loops using StringBuilder : " +
DateTime.Now.ToString(
"HH:mm:ss:ff") + "<br/>");
}
private void Iterate100K_With_StringAppend()
{
for (int i = 0; i < 99999; i++)
myString +
= i.ToString();
}
private void Iterate100K_With_StringBuilder()
{
for (int i = 0; i < 99999; i++)
sb.Append(i.ToString())
;
}
}

Your result may be slightly different from my result, but you should see signification difference on the time that it takes to perform string concatenation using string class and the time it took using StringBuilder class. The results on my test are as folows:

Start 100K loops using string catenation: 15:22:48:24
End 100K loops using string catenation : 15:26:45:20
Start 100K loops using StringBuilder : 15:26:45:20
End 100K loops using StringBuilder : 15:26:45:26

Note: Most contents are © 2007 Microsoft Corporation aside from some comments and sample code that I added.

No comments: