I went ahead and created a COM object that calls
QueryPerformanceFrequency and QueryPerformanceCounters, making
available a timer mechanism that has an effective resolution equal to
the system CPU frequency. It returns results as a double in your
choice of seconds, microseconds or nanoseconds.
The call to the timer itself seems to have an overhead of about 3-6
microseconds (on my system, in it's current state, your mileage may
vary.) (Somehow I was thinking COM overhead was more than that...)
To verify its accuracy I executed the following script:
set hrt = CreateObject("HighResTimer.HRTimer")
hrt.StartTimer
t = Timer
for i = 0 to 10000000 : Next
t2 = Timer
WScript.Echo hrt.Seconds
WScript.Echo t2 - t
The results were within a few milliseconds of each other --
expectable as the outer timer construct results include overhead
incurred by the inner one. Results were also consistent at 100M and
1M iterations (much below 1M is beyind the resolution of Timer.)
I've made this component available with C++ source at the following
address:
http://www.databoundzone.com/HighResTimer.zip. (DLL is
included, must be registered in the standard way, sources require VS6
or better to build.) Not counting the part that was generated by the
IDE, it's all of 71 lines (not including 13 lines of white space and
31 lines of file description and disclaimer.)
Hmm, it occurs to me I've needed this component for a very long
time... thanks for inspiring it!
In case you're wondering, databoundzone.com is a domain I registered,
that hopefully will soon be the home of a website dedicated to
databound UI elements in VB and HTML, the magic and mystery of
persistance provider XML, and ADO in general.
Lastly I have done some ADO profiling as part of testing this
component: for test data I used master.information_schema.Tables. I
found that the bare call to GetRows takes between 25% to 50% less
time than GetString (without taking iteration into account.)
However, when all physical memory has been allocated, and the memory
manager must virtualize new allocations, I observed GetString taking
as much as 88 times longer than GetRows! I believe it's because
GetRows allocates a series of smaller buffers, while GetString must
allocate a contiguous buffer.
For a table with all fields of a character type, GetRows must surely
consume more total memory (space for pointers to array elements as
well as the data itself) though it would be possible for GetRows to
consume less total memory, if most of it's fields were numeric (as
binary representations of most numbers take less space than text
representations of the same numbers.) But I don't think the total is
of much significance, I think the size of the largest contiguous
piece required is the issue.
I will do some more testing tomorrow.
-Mark