Qbasicnews.com

Full Version: HELP: How to measure program execution time.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
Today's machines are so fast that the TIMER function, which measures seconds, can no longer measure a program's execution time with enough accuracy.

Example: I worte a little test program that read 1000 records, did some simple process on each, and then wrote the 1000 records back out. This was on a 2.4 ghz machine, with a QuickBasic program compiled. I put a TIMER functiion up front, and one at the end, and the result was zero seconds. That is, the whole thing ran in less than 1 second.

If we wanted to have a challenge based on execution speed, how would we do it?
*****
Actually, TIMER measures 1/18.2ths of a seconds, or something like that. Anyway, check out Future.Library or UGL's timing routines - they'll measure as accuarately as you like.
Sterling,

It's not clear about TIMER and the 1/18 of a second.

I don't know what Future.lib is, and I don't know what you mean by UGL either. I'm not using QB, I'm using QuickBasic 4.5 compiled with BC.
*****
Timer is just the system timer, which refreshes 18.2 times a second by default (or 4000-something clock cycles). UGL and Future Library are asm libraries (in QLB files) that contain routines which return a more precise time. Rich Geldrich also wrote a good timer library called 'hptimer'

You can't reprogram the timer with QB because QB can't get or set interrupt vectors, so you need an ASM solution. However, there is a way to refresh the timer manually without aide of a library, and that's with a program seav originally wrote for the qb:tm. You can find it at Dav's Code Post. This works brilliantly in dos. In windows, it still updates just as fast, but it's off now and then by 1/18.2th a second because of window's shoddy dos emulation (i've never noticed it, personally).
Sometimes when a simple benchmark is all I want, I put whatever it is I'm measuring in a FOR/NEXT loop that runs through maybe 100 or 1000 times. Then you can calculate how long it would take to do it once by dividing by the number of times, manually if the result is so tiny QB rounds it to zero. Then invert it for cycles per second.

An alternative is the see how many times a section of code can be run in exactly x second. Then just divide the count by the number of seconds you chose. The longer you let it run the more accurate it will be.

Either way (fixed number of cycles and variable time dilation, or fixed number of seconds and variable number of cycles) you can give the benchmark in terms of cycles (or whatevers) per second. And these methods work fine even with TIMER as long as you allow sufficient cycles and/or seconds, and of course store the number returned by TIMER in a SINGLE type variable.
Loop the code you want to test for 5 seconds and count the number of loops..
Let's say i wanted to time MOD. Here's how i'd do it accuratly.

Code:
defint a-z

dim a as integer
dim b as integer
dim c as integer
dim i as integer
dim j as integer
dim tmrIni as single
dim tmrEnd as single

b = 1

tmrIni = timer
for  i = 0 to 549
    for  j = 0 to 16383
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
        c = a mod b
    next j
next i
tmrEnd = timer

print "It took" + str$( tmrEnd-tmrIni ) + " seconds to do 550*16384*10 MODs"
print "This computer can do" + str$(clng( 550#*16384#*10# / (tmrEnd-tmrIni) )) + " MODs per second"

You will of course need to change how many times it loops to suit your need. MOD between two integers is very fast on a athlon, that's why i had to loop it so many times. But the point is to repeat the function a couple of times inside the loop so that the actually looping time is nothing compared to the time it take to execute the function.
Sterling, Toonski, Antoni, and Blitz,
I thank you all for you insight and explanations.
I think Antoni's simple but precise solution is what I was looking for.
*****
antoni's solution is simple but not precise. besides wasting 5 seconds, your program speed can fluxtuate, and this can still only be used for delays, not for timing things.

The best solution is, if you're in dos, to use seav's precise timer sub. the best solution in windows is to use a library which i will dig off my hard drive that uses windows interrupts to create a timer device. both of these can measure down to the millisecond.
Thanks, Toonski. I'm in Windows XP. Let me know when you find the library.
*****
Pages: 1 2 3