ASP Performance

R

Roland Hall

I've read numerous articles, more than I can count, on ASP performance. I
see conflicting information so I did some tests on my own.

getstring and getrows are actually faster than recordset looping.

However, I've read in looping that Do While...Loop is the fastest and
For...Next the slowest but my tests prove otherwise.

I've tested:
Do...Loop
Do While...Loop
Do Until...Loop
While...Wend
For...Next

I didn't think I could do an accurate test with For...Each unless I used a
collection or an array.

I also see conflicting information on string concatenation and
Response.Write

Is this better?

dim str
str = str & "this "
str = str & "that "
str = str & "this and that"
Response.Write str

or this?

dim str
Response.Write "this "
Response.Write "that "
Response.Write "this and that"

I've also seen to speed the last one up:

with Response
.Write "this "
.Write "that "
.Write "this and that"
end with

Are there reliable performance tests that can be reviewed?
Does it vary between languages? ASP:VBscript, ASP:JScript, C/C++, Delphi,
VB, C#

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
D

Dave Anderson

Roland said:
Is this better?

dim str
str = str & "this "
str = str & "that "
str = str & "this and that"
Response.Write str

or this?

dim str
Response.Write "this "
Response.Write "that "
Response.Write "this and that"

Most definitely this is better than this.



--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.
 
R

Roland Hall

in message
: Roland Hall wrote:
: > Is this better?
: >
: > dim str
: > str = str & "this "
: > str = str & "that "
: > str = str & "this and that"
: > Response.Write str
: >
: > or this?
: >
: > dim str
: > Response.Write "this "
: > Response.Write "that "
: > Response.Write "this and that"
:
: Most definitely this is better than this.

What this settles this but how about that?

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
B

Bob Barrows [MVP]

Roland said:
I've read numerous articles, more than I can count, on ASP
performance. I see conflicting information so I did some tests on my
own.

getstring and getrows are actually faster than recordset looping.

However, I've read in looping that Do While...Loop is the fastest and
For...Next the slowest

I've never seen that anywhere. Do you have a cite?
but my tests prove otherwise.

I've tested:
Do...Loop
Do While...Loop
Do Until...Loop
While...Wend
For...Next

I didn't think I could do an accurate test with For...Each unless I
used a collection or an array.

I also see conflicting information on string concatenation and
Response.Write

Is this better?

dim str
str = str & "this "
str = str & "that "
str = str & "this and that"
Response.Write str

or this?

dim str
Response.Write "this "
Response.Write "that "
Response.Write "this and that"

I've also seen to speed the last one up:

with Response
.Write "this "
.Write "that "
.Write "this and that"
end with
Chris Hohmann (I think) posted the definitive analysis on this some time
ago. I don't have tome to go looking for it now, but maybe he'll pop in.
Regarding the With...End With, reducing the dots that need to be resolved
will speed things up, but
1. In vbscript, it's unlikely to be very noticeable
2. there is a threshold before which no performance enhancement will be
seen. I've seen 5 dot eliminations as the threshold but I really don't think
this has been nailed down by anyone.

Bob Barrows
 
R

Roland Hall

in message

Thanks for responding...

: Roland Hall wrote:
: > I've read numerous articles, more than I can count, on ASP
: > performance. I see conflicting information so I did some tests on my
: > own.
: >
: > getstring and getrows are actually faster than recordset looping.
: >
: > However, I've read in looping that Do While...Loop is the fastest and
: > For...Next the slowest
:
: I've never seen that anywhere. Do you have a cite?

I think I had that wrong. I never found the article I thought I remembered
reading. Now I'm wondering if I was high. It must have been between Do
While...Loop and While...Wend and may not have been a speed comparison. If
you see my mind, please post it here. I miss it.

: > but my tests prove otherwise.
: >
: > I've tested:
: > Do...Loop
: > Do While...Loop
: > Do Until...Loop
: > While...Wend
: > For...Next
: >
: > I didn't think I could do an accurate test with For...Each unless I
: > used a collection or an array.
: >
: > I also see conflicting information on string concatenation and
: > Response.Write
: >
: > Is this better?
: >
: > dim str
: > str = str & "this "
: > str = str & "that "
: > str = str & "this and that"
: > Response.Write str
: >
: > or this?
: >
: > dim str
: > Response.Write "this "
: > Response.Write "that "
: > Response.Write "this and that"

No info on the string concat?


: > I've also seen to speed the last one up:
: >
: > with Response
: > .Write "this "
: > .Write "that "
: > .Write "this and that"
: > end with
: >
: Chris Hohmann (I think) posted the definitive analysis on this some time
: ago. I don't have tome to go looking for it now, but maybe he'll pop in.
: Regarding the With...End With, reducing the dots that need to be resolved
: will speed things up, but
: 1. In vbscript, it's unlikely to be very noticeable
: 2. there is a threshold before which no performance enhancement will be
: seen. I've seen 5 dot eliminations as the threshold but I really don't
think
: this has been nailed down by anyone.

Are you saying without at least 5 statements, using with won't be a benefit,
re: threshold?

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
B

Bob Barrows [MVP]

Roland said:
in message


No info on the string concat?
That's what I was referring to here:
*********************************************
*********************************************



Are you saying without at least 5 statements, using with won't be a
benefit, re: threshold?
No, I meant without at least 5 dot-resolutions. There can be more than one
resolution per line, as in:

With document.all.tables(0).rows(0)
.style.backgroundcolor="silver"
.style.color="red"
end with

This avoids 3 dot-resolutions per line, so the threshold is passed. Again,
in vbscript, the difference will be negligible.

Bob Barrows
 
R

Roland Hall

in message
: Roland Hall wrote:
: > "Bob Barrows [MVP]" wrote in message
: > : >
: >
: > No info on the string concat?
: >
: That's what I was referring to here:
: *********************************************
: >> Chris Hohmann (I think) posted the definitive analysis on this some
: >> time ago. I don't have tome to go looking for it now, but maybe
: >> he'll pop in.
: *********************************************

Thanks for clearing that up.

: >> Regarding the With...End With, reducing the dots that
: >> need to be resolved will speed things up, but
: >> 1. In vbscript, it's unlikely to be very noticeable
: >> 2. there is a threshold before which no performance enhancement will
: >> be seen. I've seen 5 dot eliminations as the threshold but I really
: >> don't think this has been nailed down by anyone.
: >
: > Are you saying without at least 5 statements, using with won't be a
: > benefit, re: threshold?
: >
: No, I meant without at least 5 dot-resolutions. There can be more than one
: resolution per line, as in:
:
: With document.all.tables(0).rows(0)
: .style.backgroundcolor="silver"
: .style.color="red"
: end with
:
: This avoids 3 dot-resolutions per line, so the threshold is passed. Again,
: in vbscript, the difference will be negligible.

And that...
 
D

Dave Anderson

Roland said:
Is this better?

dim str
str = str & "this "
str = str & "that "
str = str & "this and that"
Response.Write str

or this?

dim str
Response.Write "this "
Response.Write "that "
Response.Write "this and that"

Seriously, I believe the second offers better performance. You could easily
test this with a large array or recordset. I tested it in JScript by reading
a SQL table of 5780 quotes totalling 357,886 bytes, or roughly 62 characters
each. To simplify testing, I dumped them into a simple JScript array and
timed the following on some old hardware, on IIS 4/5/6 and with buffering
on/off:

1. for (var i=0; i<a.length; i++) Response.Write(a)
2. for (var i=0; i<a.length; i++) str += a; Response.Write(str)
3. Response.Write(a.join(""))

Average results (10 passes):

//--- Dual XEON 550, 768MB RAM, Windows NT Server 4.0 ---//
Case Response.Buffer = true Response.Buffer = false
1. 172ms 390ms
2. 35365ms 35146ms
3. 78ms 109ms

//--- Single XEON 550, 1GB RAM, Windows 2000 Server ---//
Case Response.Buffer = true Response.Buffer = false
1. 141ms 1688ms
2. 29343ms 29177ms
3. 47ms 98ms

//--- Single XEON 550, 1GB RAM, Windows Server 2003 ---//
Case Response.Buffer = true Response.Buffer = false
1. 174ms 500ms
2. 30658ms 30540ms
3. 65ms 73ms


As you can see, concatenation is the biggest hurdle to performance, and
Array.join() beats iteration. The buffering results are self-explanatory,
though I was shocked to see how badly IIS 5 performs with buffering off[1].

I understand that in JScript, Response.Write is late-bound, which accounts
for the big difference between 1 and 3. IIRC, the same test in VBScript
yields a different result altogether. But my memory isn't what it used to
be, so I tested in IIS 6 with buffering on. I found these results[2]:

Case Response.Buffer = true
1. 50ms
2. 16912ms
3. 41ms

Once again, concatenation destroys performance, and Join() still beats
iteration.

On a side note, I compared GetRows() to GetString() for this exercise, and
GetRows() + iteration blew GetString() away. I do not speculate whether this
would be true for a recordset with multiple columns.



[1] Compared to IIS 4 and 6, that is
[2] VBScript cases:
1. For i=0 To UBound(a) : Response.Write(a(i)) : Next
2. For i=0 To UBound(a) : str = str & a(i) : Next : Response.Write(str)
3. Response.Write(Join(a))

--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.
 
C

Chris Hohmann

Dave Anderson said:
On a side note, I compared GetRows() to GetString() for this exercise, and
GetRows() + iteration blew GetString() away. I do not speculate whether
this would be true for a recordset with multiple columns.

You can side step the string buffer allocation issue with GetString making
use of the NumRows parameter to output in bursts.
 
D

Dave Anderson

Chris said:
You can side step the string buffer allocation issue with GetString
making use of the NumRows parameter to output in bursts.

Which I didn't get into, since I had already strayed well beyond the bounds
of the original question. And also because this would require me to explore
the issue of optimal block size.

The whole tradeoff between overhead and improved efficiency is quite
fascinating to me. To illustrate the problem, consider the problem of
factoring integers. Trial division is really efficient for factoring small
integers. At some point -- let's say at 5 digits -- Pollard's P-1 (or
perhaps Rho) algorithm becomes efficient enough to compensate for its
additional overhead, and is faster on average than trial division. At 40 or
50 digits, the elliptic curves algorithm starts to reign -- at least until
it reaches Quadratic Seive/GNFS territory.

This problem has a likely analogy. If we need to dump 10 rows out of a
database, it would be silly to do bursts of GetString. No doubt there is an
upper threshold above which some other technique would be optimal. So what
are we supposed to do?

In practice we rarely need to answer that question. Most web requests are
intended for an audience that cannot digest hundreds (much less hundreds of
thousands) of rows per response. In my opinion, your design is suspect long
before you reach the conclusion that you should break up your GetString call
into a bunch of smaller ones.


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.
 
C

Chris Hohmann

Dave Anderson said:
Which I didn't get into, since I had already strayed well beyond the
bounds of the original question. And also because this would require me to
explore the issue of optimal block size.

The whole tradeoff between overhead and improved efficiency is quite
fascinating to me. To illustrate the problem, consider the problem of
factoring integers. Trial division is really efficient for factoring small
integers. At some point -- let's say at 5 digits -- Pollard's P-1 (or
perhaps Rho) algorithm becomes efficient enough to compensate for its
additional overhead, and is faster on average than trial division. At 40
or 50 digits, the elliptic curves algorithm starts to reign -- at least
until it reaches Quadratic Seive/GNFS territory.

This problem has a likely analogy. If we need to dump 10 rows out of a
database, it would be silly to do bursts of GetString. No doubt there is
an upper threshold above which some other technique would be optimal. So
what are we supposed to do?

In practice we rarely need to answer that question. Most web requests are
intended for an audience that cannot digest hundreds (much less hundreds
of thousands) of rows per response. In my opinion, your design is suspect
long before you reach the conclusion that you should break up your
GetString call into a bunch of smaller ones.

Agreed. I simply wanted to comapre aples to apples. GetString + iteration
will outperform GetRows + iteration in this scenario.
 
R

Roland Hall

in message
: : > Chris Hohmann (I think) posted the definitive analysis on this some time
: > ago. I don't have tome to go looking for it now, but maybe he'll pop in.
: [snip]
:
: I'm not sure how definitive it was, but I think this is the thread you're
: talking about:
:
http://groups-beta.google.com/group..._frm/thread/8804807f08dc4c88/c89c1498e99d805e
:
: And to be fair, Dave Anderson should get equal billing for this thread.

Thanks Chris. And to give equal billing, sending a duplicate bill to Dave.
Terms: Net 7 Please pay on time to avoid late charges.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
R

Roland Hall

in message
: Roland Hall wrote:
: > Is this better?
: >
: > dim str
: > str = str & "this "
: > str = str & "that "
: > str = str & "this and that"
: > Response.Write str
: >
: > or this?
: >
: > dim str
: > Response.Write "this "
: > Response.Write "that "
: > Response.Write "this and that"
:
: Seriously, I believe the second offers better performance. You could
easily
: test this with a large array or recordset. I tested it in JScript by
reading
: a SQL table of 5780 quotes totalling 357,886 bytes, or roughly 62
characters
: each. To simplify testing, I dumped them into a simple JScript array and
: timed the following on some old hardware, on IIS 4/5/6 and with buffering
: on/off:
:
: 1. for (var i=0; i<a.length; i++) Response.Write(a)
: 2. for (var i=0; i<a.length; i++) str += a; Response.Write(str)
: 3. Response.Write(a.join(""))
:
: Average results (10 passes):
:
: //--- Dual XEON 550, 768MB RAM, Windows NT Server 4.0 ---//
: Case Response.Buffer = true Response.Buffer = false
: 1. 172ms 390ms
: 2. 35365ms 35146ms
: 3. 78ms 109ms
:
: //--- Single XEON 550, 1GB RAM, Windows 2000 Server ---//
: Case Response.Buffer = true Response.Buffer = false
: 1. 141ms 1688ms
: 2. 29343ms 29177ms
: 3. 47ms 98ms

That's a noticeable difference between NT and 2K on #1.

: //--- Single XEON 550, 1GB RAM, Windows Server 2003 ---//
: Case Response.Buffer = true Response.Buffer = false
: 1. 174ms 500ms
: 2. 30658ms 30540ms
: 3. 65ms 73ms

And not much difference between all on #3 even though 2K and 2K3 have
additional RAM.

: As you can see, concatenation is the biggest hurdle to performance, and
: Array.join() beats iteration. The buffering results are self-explanatory,
: though I was shocked to see how badly IIS 5 performs with buffering
off[1].

I guess you didn't happen to test with flushing [the data] ever so often
when buffering?!

: I understand that in JScript, Response.Write is late-bound, which accounts
: for the big difference between 1 and 3. IIRC, the same test in VBScript
: yields a different result altogether. But my memory isn't what it used to
: be, so I tested in IIS 6 with buffering on. I found these results[2]:
:
: Case Response.Buffer = true
: 1. 50ms
: 2. 16912ms
: 3. 41ms
:
: Once again, concatenation destroys performance, and Join() still beats
: iteration.
:
: On a side note, I compared GetRows() to GetString() for this exercise, and
: GetRows() + iteration blew GetString() away. I do not speculate whether
this
: would be true for a recordset with multiple columns.

That's interesting. How can I take adavantage of getRows with iteration
where I want cosmetic differences in the results. A simple example of every
other row with a different background color.

: [1] Compared to IIS 4 and 6, that is
: [2] VBScript cases:
: 1. For i=0 To UBound(a) : Response.Write(a(i)) : Next
: 2. For i=0 To UBound(a) : str = str & a(i) : Next : Response.Write(str)
: 3. Response.Write(Join(a))

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
R

Roland Hall

in message
: : > Chris Hohmann (I think) posted the definitive analysis on this some time
: > ago. I don't have tome to go looking for it now, but maybe he'll pop in.
: [snip]
:
: I'm not sure how definitive it was, but I think this is the thread you're
: talking about:
:
http://groups-beta.google.com/group..._frm/thread/8804807f08dc4c88/c89c1498e99d805e
:
: And to be fair, Dave Anderson should get equal billing for this thread.

You saying, in that thread that this:

dim arr
arr = Array("A","B","C")

is significantly better than...

dim arr
arr = split("A,B,C",",")

Where is the threshold where it becomes noticeable?

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
D

Dave Anderson

Roland said:
I guess you didn't happen to test with flushing [the data] ever so
often when buffering?!

No, because that just leads to more analysis. What if you flush the buffer
after every write? How about after every Nth write? Tedious.
That's interesting. How can I take adavantage of getRows with
iteration where I want cosmetic differences in the results. A simple
example of every other row with a different background color.

You may be confusing GetRows() with GetString(). GetRows() dumps the
recordset into a 2D array. Since you are presumably traversing that array
row-by-row already, it should be trivial to implement your cosmetic
variations.


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.
 
D

Dave Anderson

Roland said:
You saying, in that thread that this:

dim arr
arr = Array("A","B","C")

is significantly better than...

dim arr
arr = split("A,B,C",",")

Where is the threshold where it becomes noticeable?

This is not an ASP question.



--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.
 
R

Roland Hall

in message
: Roland Hall wrote:
: > I guess you didn't happen to test with flushing [the data] ever so
: > often when buffering?!
:
: No, because that just leads to more analysis. What if you flush the buffer
: after every write? How about after every Nth write? Tedious.

My goodness Dave. Obviously I'm not wanting to double processing in hopes
of decreasing latency. However, perhaps there is a potential for an
increase in performance by flusing the buffer every now and then. Saying
it's not worth considering because it requires more analysis dosen't seem
like a worthwhile response.

: >> On a side note, I compared GetRows() to GetString() for this
: >> exercise, and GetRows() + iteration blew GetString() away...
: > That's interesting. How can I take adavantage of getRows with
: > iteration where I want cosmetic differences in the results. A simple
: > example of every other row with a different background color.
:
: You may be confusing GetRows() with GetString(). GetRows() dumps the
: recordset into a 2D array. Since you are presumably traversing that array
: row-by-row already, it should be trivial to implement your cosmetic
: variations.

If is use getrows and want every other background a different color, I have
use a MOD or something to determine which will have a negative impact on the
advantage of using getrows. At this point getstring seems to have a
disadvantage since it uses markup as parameters. There is nothing that
says, use all even or all odd rows with different markup.

If the comparison is only for a drab layout, then it's not that realistic
except perhaps to an accountant. I'm still using For...Next loops, which
will require a decision to determine which row is which unless you use
alternating loops separating odd and even and that seems to be bad
alternative.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
R

Roland Hall

in message
: Roland Hall wrote:
: > You saying, in that thread that this:
: >
: > dim arr
: > arr = Array("A","B","C")
: >
: > is significantly better than...
: >
: > dim arr
: > arr = split("A,B,C",",")
: >
: > Where is the threshold where it becomes noticeable?
:
: This is not an ASP question.

It's being used on a web page with a .asp extension between <% and %>. What
would you label it?

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
B

Bob Barrows [MVP]

Roland said:
If is use getrows and want every other background a different color,
I have use a MOD or something to determine which will have a negative
impact on the advantage of using getrows.

But it still beats the alternative of looping through your recordset.
At this point getstring
seems to have a disadvantage since it uses markup as parameters.
There is nothing that says, use all even or all odd rows with
different markup.

If the comparison is only for a drab layout, then it's not that
realistic except perhaps to an accountant. I'm still using
For...Next loops, which will require a decision to determine which
row is which unless you use alternating loops separating odd and even
and that seems to be bad alternative.


Or you could incorporate some of that logic into the query that produces the
resultset.
Perhaps a computed column that indicates the color to be used for a row ...

Bob Barrows
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top