Recipe 16.2 Speeding up String Concatenation with a StringBuilder

     

16.2.1 Problem

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

16.2.2 Solution

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

Example 16-4 through Example 16-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 then calculates the average time per concatenation for the two approaches. The output of the application is shown in Figure 16-1.

Figure 16-1. Measuring string concatenation performance output
figs/ancb_1601.gif

16.2.3 Discussion

In the common language runtime (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 is "1234567890".

 
figs/vbicon.gif
 str1 = "12345" str2 = "67890" str1 = str1 & str2 
figs/csharpicon.gif
 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 actually disposed of and a new string str1 is created that contains the concatenation of str1 and str2 . As you might expect, there is a lot of overhead associated with this operation.

The StringBuilder object provides a much faster method of concatenating strings. A StringBuilder object treats strings as an array of characters that can be altered without recreating 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 already available block of memory. 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 further by setting the maximum size when the StringBuilder is created, which reduces the number of additional memory allocations that must be performed.

As Figure 16-1 shows, the performance difference between classic concatenation and concatenation using a StringBuilder object is dramatic. Classic concatenation averaged 1.0188 milliseconds per concatenation, while using a StringBuilder object averaged 0.0003 milliseconds per concatenation, which is nearly 3,000 times faster.

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

The question always arises as to when classic string manipulation or a StringBuilder should be used. Every application is different. However, if you are performing a simple concatenation of less than 5-10 strings outside of a loop (done only once), you should probably use classic string manipulation due to the overhead of creating a StringBuilder object. Anytime you are performing string manipulations within a loop or are combining many string fragments , a StringBuilder should be used. If you are not sure, set up a test similar to the one we use in our examples for this recipe and measure the two approaches yourself.


16.2.4 See Also

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

Example 16-4. Measuring string concatenation performance (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH16StringManipulationPerformanceVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH16StringManipulationPerformanceVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>String Concatenation Performance</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmStringPerformance" method="post" runat ="server"> <table width="100%" cellpadding ="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td align="center">&nbsp;</td> </tr> <tr> <td align="center" class="PageHeading"> Improving String Concatenation Performance (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <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 id="cellClassic" runat="server" align="center"></td>  </tr> <tr>  <td>Using StringBuilder</td>   <td id="cellSB" runat="server" align="center"></td>  </tr> </table> </td> </tr> </table> </form> </body> </html> 

Example 16-5. Measuring string concatenation performance code-behind (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name : CH16StringManipulationPerformanceVB.aspx.vb ' ' Description: This module provides the code behind for the ' CH16StringManipulationPerformanceVB.aspx page '***************************************************************************** Imports System Imports System.Text Namespace ASPNetCookbook.VBExamples Public Class CH16StringManipulationPerformanceVB Inherits System.Web.UI.Page 'controls on the form Protected cellClassic As System.Web.UI.HtmlControls.HtmlTableCell Protected cellSB As System.Web.UI.HtmlControls.HtmlTableCell '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.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 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 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 'CH16StringManipulationPerformanceVB End Namespace 

Example 16-6. Measuring string concatenation performance code-behind (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH16StringManipulationPerformanceCS.aspx.cs // // Description: This class provides the code behind for // CH16StringManipulationPerformanceCS.aspx // //**************************************************************************** using System; using System.Text; namespace ASPNetCookbook.CSExamples { public class CH16StringManipulationPerformanceCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.HtmlControls.HtmlTableCell cellClassic; protected System.Web.UI.HtmlControls.HtmlTableCell cellSB; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.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 classic string concatenation   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 } // CH16StringManipulationPerformanceCS } 



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

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