Recipe 19.3. Speeding Up String Concatenation with a StringBuilder


Problem

You want to reduce the time spent concatenating strings in an application that performs this operation repeatedly.

Solution

Concatenate strings with a StringBuilder object instead of the classic & and + concatenation operators.

Examples 19-4, 19-5 through 19-6 show the .aspx file and the VB and C# code-behind files for our application that demonstrates the performance difference between using the classic string operators and a StringBuilder object to perform concatenation. Our example concatenates two strings repeatedly and calculates the average time per concatenation for the two approaches. The output of the application is shown in Figure 19-1.

Figure 19-1. Measuring string concatenation performance output


Discussion

In the CLR, strings are immutable, which means that once they have been created they cannot be changed. If you concatenate the two strings, str1 and str2, shown in the following code fragment, the resulting value of str1 will be 1234567890:

 

str1 = "12345" str2 = "67890" str1 = str1 & str2

str1 = "12345"; str2 = "67890"; str1 = str1 + str2;

The way in which this concatenation is accomplished may come as a bit of a surprise to you. Since str1 cannot be changed (it is immutable), it is disposed of and a new string str1 is created that contains the concatenation of str1 and str2. As you might expect, a lot of overhead is associated with this operation.

The StringBuilder object provides a faster method of concatenating strings. A StringBuilder object treats strings as an array of characters that can be altered without re-creating the object. When a StringBuilder object is created, the CLR allocates a block of memory in which to store the string. As characters are added to a StringBuilder object, they are stored in the available memory block. If the additional characters will not fit within the current block, additional memory is allocated to store the new data.

The default capacity of a StringBuilder is 16 characters, but the number can be set to any value up to 2,147,483,647 characters, the maximum size of an integer type. If you know approximately how long the final string will be, you can improve performance by setting the maximum size when the StringBuilder is created, which reduces the number of additional memory allocations that must be performed.

As Figure 19-1 shows, the performance difference between classic concatenation and concatenation using a StringBuilder object is dramatic. Classic concatenation averaged 2.6703 milliseconds per concatenation, while using a StringBuilder object averaged 0.0004 milliseconds per concatenation, which is nearly 7,000 times faster.

StringBuilder objects are not limited to concatenation: they can support inserting, removing, replacing, and appending formatted strings. The StringBuilder is a significant improvement over the classic manipulation of strings.

The question arises as to when classic string manipulation or a StringBuilder should be used. Every application is different. However, if you are performing a concatenation of fewer than 510 strings outside of a loop (done only once), you should probably use classic string manipulation because of the overhead of creating a StringBuilder object. Any time you are performing string manipulations within a loop or are combining many string fragments, a StringBuilder should be used. If you are unsure, create a test similar to the one we use in our examples for this recipe and measure the two approaches yourself.


See Also

In the MSDN Library, search for "Use StringBuilder for Complex String Manipulation."

Example 19-4. Measuring string concatenation performance (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"   AutoEventWireup="false"   CodeFile="CH19StringConcatenationPerformanceVB.aspx.vb"   Inherits="ASPNetCookbook.VBExamples.CH19StringConcatenationPerformanceVB"   Title="String Concatenation Performance" %> <asp:Content  runat="server" ContentPlaceHolder>   <div align="center" >     Page Heading (VB)   </div>   <table width="70%" align="center" border="0"> <tr>   <td>&nbsp;</td>    <td align="center" >Time Per Concatenation (mSec)</td> </tr> <tr>   <td >Classic Concatentation</td>   <td  runat="server" align="center" ></td> </tr> <tr>   <td >Using StringBuilder</td>       <td  runat="server" align="center" ></td> </tr>   </table> </asp:Content> 

Example 19-5. Measuring string concatenation performance code-behind (.vb)

 Option Explicit On Option Strict On Namespace ASPNetCookbook.VBExamples ''' <summary> ''' This class provides the code-behind for ''' CH19StringConcatenationPerformanceVB.aspx ''' </summary> Partial Class CH19StringConcatenationPerformanceVB Inherits System.Web.UI.Page '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Private Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Const STRING_SECTION As String = "1234567890" Dim testStr As String Dim testStrBuilder As StringBuilder Dim counter As Integer Dim startTime As DateTime Dim elapsedTime As TimeSpan Dim loops As Integer 'measure the elapsed time for 10000 classic string concatenation loops = 10000 startTime = DateTime.Now() testStr = "" For counter = 1 To loops testStr &= STRING_SECTION Next elapsedTime = DateTime.Now.Subtract(startTime) 'set the table cell value to the average time per concatenation 'in milliseconds cellClassic.InnerText = _ (elapsedTime.TotalMilliseconds / loops).ToString("0.0000") 'measure the elapsed time for 1,000,000 stringbuilder concatenations 'NOTE: Many more loops were used to provide a measureable time period loops = 1000000 startTime = DateTime.Now() testStrBuilder = New StringBuilder For counter = 1 To loops testStrBuilder.Append(STRING_SECTION) Next elapsedTime = DateTime.Now.Subtract(startTime) 'set the table cell value to the average time per concatenation 'in milliseconds cellSB.InnerText = _ (elapsedTime.TotalMilliseconds / loops).ToString("0.0000") End Sub 'Page_Load End Class 'CH19StringConcatenationPerformanceVB End Namespace 

Example 19-6. Measuring string concatenation performance code-behind (.cs)

 using System; using System.Text; namespace ASPNetCookbook.CSExamples { /// <summary< /// This class provides the code-behind for /// CH19StringConcatenationPerformanceCS.aspx /// </summary> public partial class CH19StringConcatenationPerformanceCS : \ System.Web.UI.Page { ///*********************************************************************** /// <summary> /// This routine provides the event handler for the page load event. /// It is responsible for initializing the controls on the page. /// </summary> /// /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param< protected void Page_Load(object sender, EventArgs e) { const string STRING_SECTION = "1234567890"; string testStr = null; StringBuilder testStrBuilder = null; DateTime startTime; TimeSpan elapsedTime; int counter; int loops; // measure the elapsed time for 10000 stringbuilder concatenations loops = 10000; startTime = DateTime.Now; testStr = ""; for (counter = 1; counter <= loops; counter++) { testStr += STRING_SECTION; } elapsedTime = DateTime.Now.Subtract(startTime); // set the table cell value to the average time per concatenation // in milliseconds cellClassic.InnerText = (elapsedTime.TotalMilliseconds / loops).ToString("0.0000"); // measure the elapsed time for 1,000,000 classic string concatenation // NOTE: Many more loops were used to provide a measureable time period loops = 1000000; startTime = DateTime.Now; testStrBuilder = new StringBuilder(); for (counter = 1; counter <= loops; counter++) { testStrBuilder.Append(STRING_SECTION); } elapsedTime = DateTime.Now.Subtract(startTime); // set the table cell value to the average time per concatenation // in milliseconds cellSB.InnerText = (elapsedTime.TotalMilliseconds / loops).ToString("0.0000"); } // Page_Load } // CH19StringConcatenationPerformanceCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net