Author |
Topic  |
|
Deleted
deleted
    
4116 Posts |
Posted - 23 October 2002 : 15:31:52
|
Well, this is mainly an extended version of the previous test which compared const, var, dim'ed var and application variable. The test setup and the method is the same. All tests ran 10 times and the average is presented here. The iteration is set to 1 million.
The main form of the code is the same for all the tests:
<font color="blue">
' ==== START OF PRE CALCULATIONS =====
Dim str1, str2, i, ...
<font color="green">str1 = "01234567890123456789" ' 20 chars</font id="green">
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
<font color="red"> str2 = str1</font id="red">
next
response.write StopTimer(1)
</font id="blue"> In the first part (green) the data is initialized, and the second part is executed in loop (red).
Here are the tests: <font face="Lucida Console">
TEST-0 Dummy loop (ran as reference)
<font color="blue"> Dim str1, str2, i
str1 = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
' str2 = str1
next
</font id="blue">
TEST-1 constant (second reference point)
<font color="blue"> Dim str2, i
Const str1 = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1
next
</font id="blue">
TEST-2 variable
<font color="blue"> Dim str1, str2, i
str1 = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1
next
response.write StopTimer(1)
</font id="blue">
TEST-3 session("A")
<font color="blue"> Dim str1, str2, i
session("str1") = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = session("str1")
next
response.write StopTimer(1)
</font id="blue">
TEST-4 application("A")
<font color="blue"> Dim str1, str2, i
application("str1") = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = application("str1")
next
response.write StopTimer(1)
</font id="blue">
TEST-5 arr(5)
<font color="blue"> Dim str1(10), str2, i
str1(5) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1(5)
next
response.write StopTimer(1)
</font id="blue">
TEST-6 arr(5,5)
<font color="blue"> Dim str1(10,10), str2, i
str1(5,5) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1(5,5)
next
response.write StopTimer(1)
</font id="blue">
TEST-7 instr()
<font color="blue"> Dim str1, str2, i
str1 = "|0a|1b|2c|3d|4e|5f|6g|7h|8i|9j" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = mid(str1, instr(str1,"|5")+2,1)
next
response.write StopTimer(1)
</font id="blue">
TEST-8 simulated associative array (linear search)
<font color="blue"> Dim str1(2,10), str2, i, j
str1(1,5) = "55" ' 2 chars
str1(2,5) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
for j = lbound(str1,2) to ubound (str1,2)
if str1(1,j) = "55" then exit for
next
str2 = str1(2,j)
next
response.write StopTimer(1)
</font id="blue">
TEST-9 request.cookies
<font color="blue"> Dim str1, str2, i, j
response.cookies("test") = "01234567890123456789" ' 20 chars
response.cookies("test").Expires = now + 30
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = request.cookies("test")
next
response.write StopTimer(1)
</font id="blue">
TEST-10 request.servervariables
<font color="blue"> Dim str1, str2, i, j
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = request.servervariables("SCRIPT_NAME")
next
response.write StopTimer(1)
</font id="blue">
TEST-11 rs("DATA")
<font color="blue"> Dim str1, str2, i, j
Set objRS = CreateObject("ADODB.Recordset")
const adLongVarChar = 201
objRS.Fields.Append "Data", adLongVarChar, 50
objRS.Open
' Add a new record
objRS.AddNew
' Insert the data into the field
objRS("Data").AppendChunk "01234567890123456789" ' 20 chars
objRS.Update
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = objRS("Data")
next
set objRS = nothing
response.write StopTimer(1)
</font id="blue">
TEST-12 rs(0)
<font color="blue"> (same as above, except:)
for i = 1 to MaxIteration
str2 = objRS(0)
next
</font id="blue">
TEST-13 session(x) (variable version of TEST-3)
<font color="blue"> Dim str1, str2, i, x
x = "str1"
session(x) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = session(x)
next
response.write StopTimer(1)
</font id="blue">
TEST-14 application(x) (variable version of TEST-4)
<font color="blue"> Dim str1, str2, i
x = "str1"
application(x) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = application(x)
next
response.write StopTimer(1)
</font id="blue">
TEST-15 arr(i) (variable version of TEST-5)
<font color="blue"> Dim str1(10), str2, i
x = 5
str1(x) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1(x)
next
response.write StopTimer(1)
</font id="blue">
TEST-16 arr(i,j) (variable version of TEST-5)
<font color="blue"> Dim str1(10,10), str2, i, j
j = 5
str1(j,j) = "01234567890123456789" ' 20 chars
' ==== START OF LOOP (TIMED WORK)=====
StartTimer 1
for i = 1 to MaxIteration
str2 = str1(j,j)
next
response.write StopTimer(1)
</font id="blue">
</font id="Lucida Console">
Next comes the results, which are quite interesting for some operations...
|
Stop the WAR! |
Edited by - Deleted on 24 October 2002 05:37:03 |
|
HuwR
Forum Admin
    
United Kingdom
20593 Posts |
Posted - 23 October 2002 : 20:32:07
|
quote:
In the first part (green) the data is initialized, and the second part is executed in loop (red).
I must be going colour blind Bozden, I don't see any green bits 
Can't wait to see the results.< |
 |
|
HuwR
Forum Admin
    
United Kingdom
20593 Posts |
Posted - 23 October 2002 : 20:33:04
|
Would be interesting to see the different memory used by the various methods also< |
 |
|
Deleted
deleted
    
4116 Posts |
Posted - 24 October 2002 : 05:54:27
|
quote: I must be going colour blind Bozden, I don't see any green bits
Oops, corrected :)
quote: Would be interesting to see the different memory used by the various methods also
I'll do the "write performance" first. The problem with memory is this: HOW do we measure it. I could not find a technical quide or method to measure small amounts of memory used out of the heap of IIS. Two methods I can think of is:
1) Estimate them by creating thousands of resources and use Performance snap-in 2) Estimate (some of) them by counting the variable contents
I think these are not valuable enough to care... < |
Stop the WAR! |
 |
|
Deleted
deleted
    
4116 Posts |
Posted - 24 October 2002 : 08:06:01
|
Here are the results...
TEST-# AVG VAR INX-1 INX-2 ORDER DESCRIPTION
====== ===== ======= ====== ====== ===== ======================
TEST-0 0.27 0.00002 100 26 0 Dummy loop
TEST-1 1.05 0.00005 381 100 1 constant
TEST-2 1.07 0.00012 390 102 2 variable
TEST-3 9.29 0.00009 3,388 888 9 session("A")
TEST-4 9.01 0.00025 3,285 861 8 application("A")
TEST-5 1.54 0.00006 561 147 3 arr(5)
TEST-6 1.62 0.00002 590 155 4 arr(5,5)
TEST-7 4.84 0.00005 1,766 463 7 instr()
TEST-8 17.21 0.00032 6,276 1,645 13 2d-assoc.arr
TEST-9 31.02 0.00167 11,311 2,965 15 request.cookies
TEST-10 37.34 0.00182 13,616 3,569 16 request.servervariables
TEST-11 17.84 0.00185 6,505 1,705 14 rs("DATA")
TEST-12 14.98 0.00123 5,464 1,432 12 rs(0)
TEST-13 10.17 0.00004 3,708 972 10 session(x)
TEST-14 10.58 0.00080 3,856 1,011 11 application(x)
TEST-15 2.04 0.00004 744 195 6 arr(i)
TEST-16 1.63 0.00020 595 156 5 arr(i,j)
You are welcome to interprete the results ... < |
Stop the WAR! |
 |
|
pdrg
Support Moderator
    
United Kingdom
2897 Posts |
Posted - 24 October 2002 : 08:14:42
|
this is really useful stuff to know - appreciate this - thanks :-) it really shows the overhead associated with recordsets and session variables!< |
Edited by - pdrg on 24 October 2002 08:18:53 |
 |
|
HuwR
Forum Admin
    
United Kingdom
20593 Posts |
Posted - 24 October 2002 : 08:22:12
|
Thats about what I would have expected. The only sure way to test the memory would be to run the tests on a clean machine so you know that it is the only thing using the memory, that way you can just run memory sleuth or something similar.< |
 |
|
Deleted
deleted
    
4116 Posts |
Posted - 24 October 2002 : 08:27:03
|
My first impressions:
- Request.servervariables and request.cookies are very slow, it will be a good idea to use them in config.asp and save them in a variable and use them from there except specil cases of checking if they changed or not
- Arrays are not as expensive as I thought. There is almost no difference in using two dimensional arrays also.
- rs(i) style performed better than rs("field"), but not very much. It will be a good idea to continue to use the rs("field") style for the sake of easiness in development. This is also one side of the power behind getrows method.
- It has been a good idea to catch application variables into variables as known, but application variables can also keep arrays. The application variables could be grouped and accessed in one shot by taking them into arrays. This will also drop the memory requirements as the number of variable names drop.
- It will be a very bad idea to use linear search methods (i.e. looping an array or recordset) to find a record. Alternative data structures should be examined before coding it. Beware, the example I used had 10 records and I used the average 5. If the number of records/size of the array gets larger, the results will be (linearly) greater.
< |
Stop the WAR! |
 |
|
HuwR
Forum Admin
    
United Kingdom
20593 Posts |
Posted - 24 October 2002 : 09:10:06
|
quote:
It will be a very bad idea to use linear search methods (i.e. looping an array or recordset) to find a record. Alternative data structures should be examined before coding it. Beware, the example I used had 10 records and I used the average 5. If the number of records/size of the array gets larger, the results will be (linearly) greater
Do we currently do this ? I thought the only time we looped through recordsets was to display them, i know of no other way of doing that without data aware controls< |
 |
|
davemaxwell
Access 2000 Support Moderator
    
USA
3020 Posts |
Posted - 24 October 2002 : 09:24:29
|
quote: Originally posted by HuwR
quote:
It will be a very bad idea to use linear search methods (i.e. looping an array or recordset) to find a record. Alternative data structures should be examined before coding it. Beware, the example I used had 10 records and I used the average 5. If the number of records/size of the array gets larger, the results will be (linearly) greater
Do we currently do this ? I thought the only time we looped through recordsets was to display them, i know of no other way of doing that without data aware controls
Aren't there a couple places we still do the loops because of memo fields? Seems my rattled brain recalls such a situation, but for the life of me, I can't remember for sure...< |
Dave Maxwell Barbershop Harmony Freak |
 |
|
Deleted
deleted
    
4116 Posts |
Posted - 24 October 2002 : 09:29:49
|
Well, I didn't wrote these wrt the Snitz code but they were more general... I saw them in some MODs, even in the code I wrote. I didn't actually examine v3.4 code that much, because the results were already great thanks to dev-team, Richard in particular .
Of course you have to loop to print the records. What I meant was "find and process"... But even in that case, it can be better than using connection.execute every single one... < |
Stop the WAR! |
 |
|
HuwR
Forum Admin
    
United Kingdom
20593 Posts |
Posted - 24 October 2002 : 10:04:28
|
Was just checking don't want tto give Richard a heart attack just yet 
quote:
Aren't there a couple places we still do the loops because of memo fields?
I gues Richard could best answer that, but I don't think so, what bozden is talking about is looping through a recordset until you find a matching record then process it (I think), I'm pretty sure we don't do that anywhere< |
 |
|
Deleted
deleted
    
4116 Posts |
|
alex042
Average Member
  
USA
631 Posts |
Posted - 24 October 2002 : 11:12:03
|
quote: Request.servervariables and request.cookies are very slow, it will be a good idea to use them in config.asp and save them in a variable and use them from there except specil cases of checking if they changed or not
Interesting. I wonder if this is due to hardware interaction. i.e. hard drive reads. I guess this means I should rewrite part of IPGate since it calls these everytime it's included in a page which may be for every page on many sites. 
< |
 |
|
Deleted
deleted
    
4116 Posts |
Posted - 24 October 2002 : 11:24:44
|
quote:
Interesting. I wonder if this is due to hardware interaction. i.e. hard drive reads.
Actually there is no network delay (client running on the server), so the actual cookie performance would never be so good. < |
Stop the WAR! |
 |
|
work mule
Senior Member
   
USA
1358 Posts |
Posted - 24 October 2002 : 13:18:40
|
Interesting to see the actual results.
After seeing actual results, it helps put things into perspective when reading the 25+ ASP Tips to Improve Performance and Style article on MSDN.
quote: Request.servervariables and request.cookies are very slow, it will be a good idea to use them in config.asp and save them in a variable and use them from there except specil cases of checking if they changed or not
I think that's why it's recommended that anytime you need to reference anything in the Request Object more than once, you should assign it to a variable.
quote: It has been a good idea to catch application variables into variables as known, but application variables can also keep arrays. The application variables could be grouped and accessed in one shot by taking them into arrays. This will also drop the memory requirements as the number of variable names drop.
Looking at the results, I would agree with the idea of storing the snitz configuration as an array in an application variable. Yes, there is mention that storing large arrays this way isn't good, but the example was 100,000 elements and Snitz uses around 150. I don't think the amount of elements a Snitz array would use would be a problem at all. < |
 |
|
|
Topic  |
|
|
|