Response.Write speed problem

1 view
Skip to first unread message

Robert Mullen

unread,
Jun 2, 2001, 2:12:52 PM6/2/01
to
I have code in a COM+ .dll that is looping through a 2 dimensional variant array
and writing an html table to the response stream. This table can be 20 columns by
500-800 rows and is taking about 17 seconds to generate in VB. I am using the
ASPTypeLibrary.Response object and performing a response.write at every line of
VB code as opposed to building it in a buffer and sending it at one time. 17
seconds is a ridiculous amount of time for this to take. While I do have a case
statement and some if...then's in the loop, there are no inner loops or other
obvious (at least to me) coding no-no's. Can anybody tell me if there is a much
faster way to write this amount of formatted html from a COM+ componenet?

TJS

unread,
Jun 2, 2001, 4:43:47 PM6/2/01
to
I would build up the html string and use one response.write statement to
send the whole thing at one time to client.


"Robert Mullen" <rmu...@qwest.net> wrote in message
news:53de01c0eb8f$a3bcbd40$19ef2ecf@tkmsftngxa01...

..

unread,
Jun 3, 2001, 8:56:46 AM6/3/01
to
Hi,

I would think that building up a string would slow things down, not up.
But, of course, the best way to tell is to try in your given environment.

Another suggestion would be to try using XML and XSLT to generate the HTML.
You can send the transformation directly to the Response object. I don't
know if that is an option for you, or how the performance compares to more
traditional methods.

I am assuming that your array gets its data by using rs.GetRows. If so, and
if you have the flexibility, I would recommend trying to work with your data
in other ways. Try using rs.GetString to create an HTML string that
generates the table rows (add <tr>'s and <td>'s to the data as you stick it
into the string), or try working with the recordset as you write out data.
Typically, using rs.GetRows is the fastest way to retrieve a recordset and
pass it through various layers / tiers. At some point, however, with larger
datasets, you might gain speed by using the ADO recordset.

A comment you might hear from someone else: this seems like quite a large
amount of data to be presenting in one page. Have you though about using
paging, such that users only see, say 50, records at a time?

I also assume that you *have* to do this from a component, no? If you have
some flexibility, play with returning the variant arrays to ASP and
processing it with VBScript or JScript on the server.

Best of luck! Let us know what you end up doing....

"TJS" <nospa...@here.com> wrote in message
news:u4JPJR66AHA.1496@tkmsftngp03...

Antonin Foller

unread,
Jun 3, 2001, 3:33:53 PM6/3/01
to
Do you have Response.Buffer = true?

What is the time to get 800*20 values (without response.write)? May be,
array enumaration takes the time? If not, you can use some kind of bufferred
string using Mid statement.

Antonin Foller
PSTRUH Software
http://www.pstruh.cz

"Robert Mullen" <rmu...@qwest.net> wrote in message
news:53de01c0eb8f$a3bcbd40$19ef2ecf@tkmsftngxa01...

Steve Smith

unread,
Jun 3, 2001, 5:34:48 PM6/3/01
to
One of the slowest things to do in VB is string manipulation.
Try this it should give a massive increase in speed.
Get the code right as it uses pointers.

New class file

Option Explicit

Private Declare Sub CpyMem Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal length As
Long)
Private m_Buffer() As Byte
Private m_NextFreeElement As Long
Const DEFAULT_INCREM As Long = 50

Public Sub Append(sStr As String)
Dim strLen As Long
Dim nNeeded As Long
strLen = Len(sStr)
nNeeded = m_NextFreeElement + strLen
Do Until (UBound(m_Buffer) >= nNeeded)
ReDim Preserve m_Buffer(0 To (UBound(m_Buffer) + DEFAULT_INCREM))
Loop
CpyMem m_Buffer(m_NextFreeElement), ByVal sStr, strLen
m_NextFreeElement = m_NextFreeElement + strLen
End Sub

Public Sub Clear()
ReDim m_Buffer(DEFAULT_INCREM)
m_NextFreeElement = 0
End Sub

Public Property Let Value(ByVal sNewString As String)
Me.Clear
Me.Append sNewString
End Property

Public Property Get Value() As String
Value = String$(m_NextFreeElement, 0)
CpyMem ByVal Value, m_Buffer(0), m_NextFreeElement
End Property

Public Property Get Size() As Long
Size = m_NextFreeElement
End Property

Private Sub Class_Initialize()
ReDim m_Buffer(DEFAULT_INCREM)
m_NextFreeElement = 0
End Sub

Private Sub Class_Terminate()
Erase m_Buffer
End Sub


Now do this

Dim x as Newclass
Public Function Doit()
Set x = new NewClass
with x
.clear
.Append "<html>"
etc,etc
.Append "</html>"
m_Response.Write .Value
end with
Set x = nothing
end function

I have seen incrreases of uto 700 times with this

Hope this helps

Steve


"Robert Mullen" <rmu...@qwest.net> wrote in message
news:53de01c0eb8f$a3bcbd40$19ef2ecf@tkmsftngxa01...

Robert Mullen

unread,
Jun 3, 2001, 5:51:56 PM6/3/01
to
I have found this to be the slowest method of writing out large streams of data.
The same routine that takes 17 seconds when split up into many response.writes
takes nearly 50 seconds if it is concatenated and sent at once. VB's string
operations are easy but slow. I am thinking that I may go this route only write
this part of the component in C++ instead. Anybody tried this?


.

Robert Mullen

unread,
Jun 3, 2001, 5:59:30 PM6/3/01
to
I had not thought about this. When I set response.buffer = true at the beginning
of my routine and then flush at the end, it takes about 10 seconds longer than if
I do it with many response.writes. It appears this far that you must strike a
happy medium between the two relatively slow operations (response.write and VB
string concatenation) because if I remove ALL string concatenation from my
routine (which creates around 100 response.writes due to the complexity of this
table) then it slows it down about 5 seconds. It seems that if I keep the string
concatenation to about a readable line length, the balance is fairly optimal.

I was hoping to write a fixed length string and use the mid statements as you
suggested (I have read that this is a fairly fast approach) but my output text is
over 170k which will not fit into the biggest fixed length string VB can provide.


.

Robert Mullen

unread,
Jun 3, 2001, 6:04:37 PM6/3/01
to
Thanks, this is just what I was looking for. I won't have time to put it to work
until Monday but I will give a report back then and let any interested parties
know what the results were.

New class file

Option Explicit


Now do this

Hope this helps

Steve


.

Robert Mullen

unread,
Jun 3, 2001, 6:17:32 PM6/3/01
to
My experience with XML and XSL to this point have been rather slow. I may go this
route for the sake of knowledge anyway but this table is fairly complex as it has
fully controlled multi-columns sorting ability, dynamic column inclusion and
ordering, as well as color coding, in-row buttons, and hyperlinks. I am caught
trying to replicate a full featured grid control with a DHTML table and it has
gotten pretty involved as you might imagine. With all that said, I do not think I
know anywhere near enough XSLT to make that work so the learning curve may be
prohibitive.

As for the size of the results, I am trying to convince my user base that they do
not need to see their entire inventory at one time (this is a truck load building
and dispatch app) and I have built in both row limits and very flexible filtering
but they don't want to use it. This is really a user management issue and so far
I haven't struck the right chord with them (I am nearly ready to strike something
else in the hope of bringing about change) and unfortunately, whether they use
the system properly or not, their perception of system speed and their relation
of this perception to other users and management is the battle I am currently
fighting.

Also, it has always been my perception that compiling these types of operations
into a component would bring about a speed increase over interpreted script. I
know that there is added overhead in COM+ but this is exactly the type of
application I have heard will gain from COM+ the most. Does anyone have direct
experience comparing the two?

-----Original Message-----
Hi,


.

TJS

unread,
Jun 3, 2001, 11:38:30 PM6/3/01
to
This may help too

http://msdn.microsoft.com/workshop/server/asp/ASPtips.asp#asptips_tip14


visit http://www.ASPkey.com


"Robert Mullen" <rmu...@qwest.net> wrote in message

news:3e3501c0ec77$68371e80$9ae62ecf@tkmsftngxa02...

..

unread,
Jun 4, 2001, 10:51:35 AM6/4/01
to
Robert,

You might want to take a look at:

http://msdn.microsoft.com/library/techart/Docu2kbench.htm

if you haven't seen it already (Architecture Decisions, the Nile
application).

>>>
Also, it has always been my perception that compiling these types of
operations
into a component would bring about a speed increase over interpreted script.
I
know that there is added overhead in COM+ but this is exactly the type of
application I have heard will gain from COM+ the most. Does anyone have
direct
experience comparing the two?
<<<

I guess "it depends." If you are using Windows 2000, you might try moving
your presentation code out of the component and into an ASP document. I'm
sure you'll see a big increase in performance by following Steve Smith's
suggestion / code. Along those lines, you could also check out

http://www.devx.com/free/tips/tipview.asp?content_id=3387

which is a snippet to create a huge string chunks at a time. If you follow
Steve's code, I'd monkey around with the buffer size....

From the other stuff you said, it seems like an XML/XSLT would be a very bad
solution for your current situation. I haven't used it for any large
application, so I don't have any idea on how the performance rates. Like
you mentioned -- when you get a minute to breathe after increasing
performance dramatically -- you might want to re-implement your solution
with XML/XSLT just for the learning experience.

..


Reply all
Reply to author
Forward
0 new messages