Compartir a través de


String Concatenation vs String Builder - The performance hit! See it to believe it :o)

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="https://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. (https://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.

String concatenation - Explanation(Look out for the String Concatenation section)
How to improve string concatenation performance in Visual Basic.NET
How to improve string concatenation performance in Visual C#

Hope that helps!

Cheers,
Rahul

Comments

  • Anonymous
    August 29, 2006
    Just curious have you seen any studies done for small string Concatenation. I have done some experimenting on my own with a variety of different methods and building up small strings seem that Concatenation is the best way to do this from a perf angle.

    For Example where I is an int and tempString is just a small string like a say a user name or a guid.:
    Console.WriteLine(i.ToString() + " - " + tempString);
    Seems to get better performance, than say this
    Console.WriteLine("{0} - {1}",i,tempString);

    Again we are talking Milliseconds in performance but if you are doing a lot of this like say in a log file or something the milliseconds can add up. Anyway this is just from my experiments. However there could be other things I am not thinking of so I thought I would ask.

  • Anonymous
    August 29, 2006
    I find it interesting that you didn't compare the results of directly streaming the results out to the response against the stringBuilder. It appears that the string builder is nearly 5 times slower than just using Response.Write. The point of the StringBuilder vs. String Concatenation is quite valid of course.

  • Anonymous
    August 29, 2006
    Honestly, I haven't experimented much on it yet! I will try some stuff offline and post it here as soon as I get enough time. Thanks for bringing this point!

    Thanks,
    Rahul

  • Anonymous
    August 29, 2006
    Jim, the reason I didn't compare the results is that you can't manipulate the strings after you have put it in the Response.Write. So, it would be rather unfair to compare String Concat or StringBuilder to directly writing in the response.

    Still, I wanted to show the output, so that atleast people are aware which route to take :o)

    Although, as you noticed already, writing to the Response directly is the fastest (but least flexible)!

  • Anonymous
    September 09, 2006
    Ok, so I was just planning to do some more experimentation and find out the perfect deal between String Concatenation and String Builder and got a link which I found quite interesting.

    http://www.hanselman.com/blog/StringBuildersVsStringConcatenation.aspx.

    Hope this helps!
    Rahul

  • Anonymous
    April 04, 2008
    Fine. But is there any limit on the length of string. If so, is there any other alternative for it. Does stringbuilder allows more characters than string?

  • Anonymous
    April 17, 2009
    I did some experminets on StringBuilder and String based on this article and you can see my results. http://www.robinthomas.in/dotnet/stringbuilder-vs-string-concatenations/