Tuesday, December 14, 2010

String Vs StringBuilder

from my Standpoint I would say string builder is better than strings. rest of the stories can be seen here.

In this post, I am going to discuss about using String Concatenation vs String Builder. I have created a very simple page which creates a string using three different methods.

1) Writes directly to the Response Cache
2) Creates a String variable using String concatenation
3) Creates a String variable using String Builder

I have tried to keep it as simple and self explanatory. Basically there is a string variable called strSample which is 64 bytes in size, and I use simple loops to create strings of the required size and discuss about performance accordingly.

Lets begin by creating an aspx file (say, StringPerf.aspx) in your C:\Inetpub\WWWroot folder (or any other virtual folder of your choice). Now, open StringPerf.aspx in Notepad and paste the following code...

<%@ Page Language="vb" trace="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
  <title>StringPerf</title>
  <script runat="server">
'At this point I am declraring a string which is 64 bytes
Dim strSample As String = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
Dim intListValue As Integer
Dim i As Integer
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Put user code to initialize the page here
    Response.Write("<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><HR>")
    intListValue = Val(DropDownList1.SelectedValue)
End Sub
Private Sub btnResponseWrite_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Trace.Write("In Response Write before writing")
    For i = 1 To 16 * intListValue
        Response.Write(strSample)
    Next
    Trace.Write("In Response Write after writing")
End Sub
Private Sub btnStringConcat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim strConcat As String
    Trace.Write("In String Concatenation before concatenating")
    For i = 1 To 16 * intListValue
        strConcat += strSample
    Next
    Trace.Write("Length of the string = " & strConcat.Length)
    Trace.Write("In String Concatenation after concatenating")
    Response.Write(strConcat)
End Sub
Private Sub btnStringBuilder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim stbBuilder As New StringBuilder
    Trace.Write("In String builder before building")
    For i = 1 To 16 * intListValue
        stbBuilder.Append(strSample)
    Next
    Trace.Write("Length of the string = " & stbBuilder.Length)
    Trace.Write("In String builder after building")
    Response.Write(stbBuilder.ToString)
End Sub
  </script>
  <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
  <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
  <meta name="vs_defaultClientScript" content="JavaScript">
  <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
  <form id="Form1" method="post" runat="server">
   <asp:Button id="btnResponseWrite" onclick=btnResponseWrite_Click style="Z-INDEX: 103; LEFT: 24px; POSITION: absolute; TOP: 104px" runat="server" Text="Response.Write" Width="196px"></asp:Button>
   <asp:Button id="btnStringConcat" onclick=btnStringConcat_Click style="Z-INDEX: 101; LEFT: 24px; POSITION: absolute; TOP: 136px" runat="server" Text="String Concatenation" Width="196"></asp:Button>
   <asp:Button id="btnStringBuilder" onclick=btnStringBuilder_Click style="Z-INDEX: 102; LEFT: 24px; POSITION: absolute; TOP: 168px" runat="server" Text="String Builder" Width="196px"></asp:Button>&nbsp;
   <asp:Label id="Label1" style="Z-INDEX: 104; LEFT: 24px; POSITION: absolute; TOP: 32px" runat="server"
    Font-Bold="True" Font-Names="Arial"> In this sample, we will see the performance difference in using String Concatenation vs String Builder</asp:Label>
   <asp:Label id="Label2" style="Z-INDEX: 105; LEFT: 104px; POSITION: absolute; TOP: 72px" runat="server"
    Width="56px" Font-Bold="True" Height="19">KB</asp:Label>
   <asp:DropDownList id="DropDownList1" style="Z-INDEX: 106; LEFT: 24px; POSITION: absolute; TOP: 69px"
    runat="server" Height="19px" AutoPostBack="True">
    <asp:ListItem Value="1">1</asp:ListItem>
    <asp:ListItem Value="2">2</asp:ListItem>
    <asp:ListItem Value="4">4</asp:ListItem>
    <asp:ListItem Value="8">8</asp:ListItem>
    <asp:ListItem Value="16">16</asp:ListItem>
    <asp:ListItem Value="32">32</asp:ListItem>
    <asp:ListItem Value="64">64</asp:ListItem>
    <asp:ListItem Value="128">128</asp:ListItem>
    <asp:ListItem Value="256">256</asp:ListItem>
    <asp:ListItem Value="512">512</asp:ListItem>
    <asp:ListItem Value="1024">1024</asp:ListItem>
   </asp:DropDownList>
  </form>
</body>
</HTML>

Save the aspx file and browse it. (http://localhost/StringPerf.aspx). You should be able to see a page with a drop down combo box with three buttons called Response.Write, String Concatenation and String Builder. I have turned trace to "true" in the page so that we could see how much time is taken for a similar operation using different methods.

Cool!! Time to start testing :o)

Scenario 1
Combo Box set to 4 KB.

a) Trace With "Response.Write" looks similar to (have a look at the trace generated)

In Response Write before writing 0.00105879378524366 0.000030
In Response Write after writing 0.00112276839654202 0.000064

b) Trace With "String Concatenation" looks similar to

In String Concatenation before concatenating 0.000805130260968922 0.000029
Length of the string = 4096 0.00130072397469511 0.000496
In String Concatenation after concatenating 0.00135128906048115 0.000051
Time taken = 0.00135128906048115 - 0.000805130260968922 = 0.000546158799512228

c) Trace With "String Builder" looks similar to

In String builder before building 0.000985041394925891 0.000030
Length of the string = 4096 0.00104063505277905 0.000056
In String builder after building 0.00106298426196626 0.000022
Time taken = 0.000077942867040369

It looks pretty harmless, isn't it? And in fact for small strings, it doesn't make too much difference anyways. Now look at another scenario. The "Time Taken" what I have calculated above will vary from system to system, but I hope it sohuld give you the idea.

Scenario 2
Combo Box set to 256 KB.

a) Trace With "Response.Write" looks similar to (have a look at the trace generated)

In Response Write before writing 0.000857650902558845 0.000030
In Response Write after writing 0.00188180341356234 0.001024

b) Trace With "String Concatenation" looks similar to

In String Concatenation before concatenating 0.000866590586233725 0.000029
Length of the string = 262144 15.6489126411318 15.648046
In String Concatenation after concatenating 15.6490316506707 0.000119
Time taken = 15.648165060084466275

c) Trace With "String Builder" looks similar to

In String builder before building 0.00103979695743453 0.000029
Length of the string = 262144 0.00564960071740961 0.004610
In String builder after building 0.00575743565173786 0.000108
Time taken = 0.00471763869430333

Now, here comes the difference. And what an amount! String Builder is performing almost ~3317 times faster than String Concatenation (15.648165 / 0.004717)!!!

As you can see the performance dips down drastically. And thankfully, we have an explanation. Visit the following links and enlighten yourself. You may try with different values in the Combo box and see for yourself how badly it can effect your server's performance.

Sources to

http://blogs.msdn.com/b/rahulso/archive/2006/08/29/string-concatenation-vs-string-builder-_2d00_-the-performance-hit_2100_-see-it-to-believe-it-_3a00_o_2900_.aspx

http://support.microsoft.com/?id=893660

http://support.microsoft.com/?id=306821

http://support.microsoft.com/?id=306822

Interesting Discussions

http://channel9.msdn.com/Forums/TechOff/14294-C-string-vs-StringBuilder

http://channel9.msdn.com/Forums/TechOff/211803-Net-String-vs-StringBuilder-metrics

nice and short article

http://blogs.msdn.com/b/msdnstudentflash/archive/2005/01/31/364217.aspx

Detailed explanations

http://www.codeproject.com/KB/string/string.aspx

http://www.codeproject.com/KB/cs/StringBuilder_vs_String.aspx

More blog

http://www.google.com/search?sourceid=navclient&ie=UTF-8&oe=UTF-8&q=site%3Ablogs.msdn.com+string+stringbuilder

A Bit more detail

http://blogs.msdn.com/b/ricom/archive/2003/12/02/40778.aspx

http://blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx

No comments: