Solved

ASP String concatenation

Posted on 2004-09-14
8
8,209 Views
Last Modified: 2012-05-05
I have read several articles (for example, www.adopenstatic.com/experiments/stringconcatenation.asp) where the inefficiency of string concatentation is discussed.

I have lots of code that builds a web page with a long sequence of string concatenations, such as the following:

strHTML = ""
strHTML = strHTML & strHTMLcode1
strHTML = strHTML & strHTMLcode2
strHTML = strHTML & strHTMLcode3
strHTML = strHTML & strHTMLcode4
strHTML = strHTML & strHTMLcode5
strHTML = strHTML & strHTMLcode6

and so on, where "strHTMLcodeX" is some actual HTML. These concatenations often go on for between 50 or 100 lines (maybe more).

The code is not necessarily needed right away, so simple replacement with Response.Write calls would not often be the best approach.

My first inclincation would simply to replace the above with the following:

strHTML = strHTMLcode1  & strHTMLcode2 & strHTMLcode3 & strHTMLcode4  & strHTMLcode5 & strHTMLcode6

However, this seems kind of ugly, especially with 100 variables and literals.

Can anyone recommend a nicer approach?
0
Comment
Question by:jasimon9
8 Comments
 
LVL 39

Expert Comment

by:appari
Comment Utility
it seems you are generating complete HTML code in asp and using response.write

if that is the case instead of using response.write, even for static HTML, keep static HTML as it is and use ASP code to generate only the dynamic part of the page.
0
 
LVL 21

Assisted Solution

by:ap_sajith
ap_sajith earned 50 total points
Comment Utility
An easy way round is..

strHTML = strHTML &_
            strHTMLcode1  &_
            strHTMLcode2 &_
            strHTMLcode3 &_
            strHTMLcode4 & _
            strHTMLcode5 &_
            strHTMLcode6

The reason why this is less strenuous because the strHTML variable doesnt have to be reassigned each time. The main reason for string concatenations spiking up the CPU usage is the memory reallocation required each tim you reassign a variable. This method also improves readability... even for 100 lines :)

There is a much more efficient and neater method using a string concatenation calss.

http://www.15seconds.com/howto/pg000929.htm

The class is really efficient and works wonders with the CPU usage :)

Hope this helps..

Cheers!!
0
 

Author Comment

by:jasimon9
Comment Utility
To appari: of course you are correct, when the HTML is statis. The whole point of building the HTML in ASP is because it is dynamic. I did not specifically say so, assuming that it would be obvious.
0
 

Author Comment

by:jasimon9
Comment Utility
To ap_sajith: your first suggestion provides a way to make the code more readable, but otherwise is the same as the alternative I proposed. A slight improvement.

I will check out your second suggestion at 15seconds.com.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:jasimon9
Comment Utility
Looking at the StringBuilder class: has anyone done any performance comparisons against simply

strHTML = strHTMLcode0 &_
          strHTMLcode1  &_
          strHTMLcode2 &_
          strHTMLcode3 &_
          strHTMLcode4 & _
          strHTMLcode5 &_

...
          strHTMLcodeX

where the "X" is a pretty large number?
0
 
LVL 5

Accepted Solution

by:
ajitanand earned 75 total points
Comment Utility
Hello,

String concatenating is VBScript is too slow. Rather use this FastString Class:
------------------------------
<%
Class FastString
      Dim stringArray, growthRate, numItems

      Private Sub Class_Initialize()
            growthRate = 50: numItems = 0
            ReDim stringArray(growthRate)
      End Sub

      Public Sub Append(ByVal strValue)
            ' next line prevents type mismatch error if strValue is null. Performance hit is negligible.
            strValue=strValue & ""
            If numItems > UBound(stringArray) Then ReDim Preserve stringArray(UBound(stringArray) + growthRate)
            stringArray(numItems) = strValue:numItems = numItems + 1
      End Sub

      Public Sub Reset
            Erase stringArray
            Class_Initialize
      End Sub
      
      Public Function concat()
            Redim Preserve stringArray(numItems)
            concat = Join(stringArray, "")
      End Function
End Class
%>
-----------------------------------

To use it you just need to call as following:
<%
'Call the following once...
Dim ofast
Set oFast = New FastString

'Do this whenever you want...
oFast.Reset
oFast.Append "This is a substring1!"
oFast.Append "This is a substring2!"
oFast.Append "This is a substring3!"

Response.Write oFast.Concat

'Start again!
oFast.Reset
oFast.Append "This is a substring4!"
oFast.Append "This is a substring5!"
oFast.Append "This is a substring6!"

oFast.Reset
Response.Write oFast.Concat

Set oFast = Nothing
%>

----------------------------------------

This code gives you a HUGE performance benefit.

Hope this helps.

warm regards,
Ajit Anand
0
 

Author Comment

by:jasimon9
Comment Utility
I have tested the StringBuillder suggested by ap_sajith (from http://www.15seconds.com/howto/pg000929.htm) and
FastString suggested by ajitanand. Both are extremely similar, with some additional error checking in FastString to prevent errors if the string argument is NULL.

My first tests showed StringBuilder with a slight but consistent speed advantage. However, passing a NULL string did cause it to crash. By adding the one line of code from FastString to StringBuilder (strValue=strValue & ""), the crashing is prevented and both algorithms run about the same speed.

Normally, I would give points to the first responder when answers are essentially identical. However, because of the slight superiority of FastString due to the error checking, I am going to split the points. I guess if you could always be assured that no NULLs would occur then you could omit the error checking. However, I believe this would not be good practice.

Here is a typical timing output  for 10000 iterations with the corrected StringBuilder (string output omitted):

Plain Concatentation: 5.265625
******
Using FastString: 0.1992188
******
Using StringBuilder: 0.203125

As you can see, either algorithm (when corrected for NULL) is acceptable and a big improvement over plain concatentation. Even greater gains observered with 20000 iterations.

Incidentally, for a small number of iterations, plain concatenation is almost as fast. For 1000 iterations, here are the timings:

Plain Concatentation: 0.046875
******
Using FastString: 0.015625
******
Using StringBuilder: 0.015625

Here is the code used to run the test. YMMV.

<%
' Use this class to concatenate strings in a much more
' efficient manner than simply concatenating a string
' (strVariable = strVariable & "your new string")
Class StringBuilder
      Dim arr       'the array of strings to concatenate
      Dim growthRate  'the rate at which the array grows
      Dim itemCount   'the number of items in the array

      Private Sub Class_Initialize()
            growthRate = 50
            itemCount = 0
            ReDim arr(growthRate)
      End Sub

      'Append a new string to the end of the array. If the
      'number of items in the array is larger than the
      'actual capacity of the array, then "grow" the array
      'by ReDimming it.
      Public Sub Append(ByVal strValue)
        strValue=strValue & ""  'code borrowed from FastString to prevent crash on NULL'
            If itemCount > UBound(arr) Then
                  ReDim Preserve arr(UBound(arr) + growthRate)
            End If

            arr(itemCount) = strValue
            itemCount = itemCount + 1
      End Sub

      'Concatenate the strings by simply joining your array
      'of strings and adding no separator between elements.
      Public Function ToString()
            ToString = Join(arr, "")
      End Function
End Class

Class FastString
     Dim stringArray, growthRate, numItems

     Private Sub Class_Initialize()
          growthRate = 50: numItems = 0
          ReDim stringArray(growthRate)
     End Sub

     Public Sub Append(ByVal strValue)
          ' next line prevents type mismatch error if strValue is null. Performance hit is negligible.
          strValue=strValue & ""
          If numItems > UBound(stringArray) Then ReDim Preserve stringArray(UBound(stringArray) + growthRate)
          stringArray(numItems) = strValue:numItems = numItems + 1
     End Sub

     Public Sub Reset
          Erase stringArray
          Class_Initialize
     End Sub

     Public Function concat()
          Redim Preserve stringArray(numItems)
          concat = Join(stringArray, "")
     End Function
End Class

Dim iTime1, iTime2, iX, iLimit
iLimit = 10000

'plain concatentation'
dim strVar
iTime1 = Timer
strVar = "<br>"
for iX = 1 to iLimit
      strVar = strVar & "this is Plain1|"
next
iTime2 = Timer
Response.Write("<br>Plain Concatentation: " & iTime2 - iTime1)
Response.Write(strVar)

'using FastString'
Dim ofast
Set oFast = New FastString
iTime1 = Timer
oFast.Reset
oFast.Append "<br>"
oFast.Append NULL
For iX = 0 To iLimit
      oFast.Append("this is Fancy2")
Next
iTime2 = Timer
Response.Write("<br>******")
Response.Write("<br>Using FastString: " & iTime2 - iTime1)
Response.Write oFast.Concat
Set oFast = Nothing

'using StringBuilder'
Dim objBuilder
Set objBuilder = new StringBuilder
iTime1 = Timer
objBuilder.Append("<br>")
objBuilder.Append(NULL)
For iX = 0 To iLimit
      objBuilder.Append("this is Fancy1")
Next
iTime2 = Timer
Response.Write("<br>******")
Response.Write("<br>Using StringBuilder: " & iTime2 - iTime1)
Response.Write objBuilder.ToString()
Set objBuilder = nothing

%>
0
 
LVL 21

Expert Comment

by:ap_sajith
Comment Utility
@Jasimon, Thank you for posting back the results of your testings. I know the faststring class from the following article in eggheadcafe.com. I did not post it because of the obvious reason that it is similar to the stringbuilder class.
http://www.eggheadcafe.com/articles/20011227.asp

The article even has a link that lets you test the performance.

>>To ap_sajith: your first suggestion provides a way to make the code more readable, but otherwise is the same as the alternative I proposed. A slight improvement.<<

Well, I had overlooked your comment (strHTML = strHTMLcode1  & strHTMLcode2 & strHTMLcode3 & strHTMLcode4  & strHTMLcode5 & strHTMLcode6).

As for the points, i am not here for the points any more.....well... atleast for now ;o)....Dont really have the time to spare.

Once again, thanks for posting the excellent feedback.

Cheers!!
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

I have helped a lot of people on EE with their coding sources and have enjoyed near about every minute of it. Sometimes it can get a little tedious but it is always a challenge and the one thing that I always say is:  The Exchange of information …
I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now