The Database Managers, Inc.

Contact The Database Managers, Inc.


Use an RSS enabled news reader to read these articles.Use an RSS enabled news reader to read these articles.

DataFlex Decompiler
Page 6

Timing an Event in DataFlex

by Curtis Krauskopf

Measuring the SET_TIMER ResolutionMeasuring the SET_TIMER Resolution

The SET_TIMER command allows the programmer to create code that executes when the keyboard is waiting for input. This means that you can't use SET_TIMER to test how long a report takes to run, or how long a record takes to save. But you can use it to find out how long the system has been waiting on the user before they acknowledge a prompt.

According to the DataFlex documentation, the accuracy of the SET_TIMER command is dependent on the operating system. The timer has a documented resolution of 1/100th of a second but, according to DAC's documentation:

"... most operating systems do not return time intervals with this much accuracy."

So, the question is, what kind of accuracy is available through SET_TIMER on your operating system?

A program that provides an answer to this is below. testtime.src is designed to test the minimum resolution that the SET_TIMER command uses on a particular operating system. In testtime.src, the SET_TIMER command is executed with a user-defined periodic interval. testtime.src will count how many times per second that the user-defined interval fires or executes. The result displayed by testtime.src shows how many times per second the interval executed.

For example, if testtime.src reports that the timing event fired 4 times in a second, then that means that the timing event is firing every 0.250 seconds. Similarly, if testtime.src reports that the timing event fired 18 times per second, then each timing event is firing every 1/18 = 0.0556 seconds.

The way to find out the maximum resolution that DataFlex uses on your operating system is this: run testtime with the minimum resolution (1, which means 1/100th of a second). testtime will report how many times per second the timing event is executing. The reciprocal of that number is the amount of time, per second, for the minimum resolution for your operating system and machine.


// testtime.src
// 
// by Curtis Krauskopf
// (c) 2003 The Database Managers, Inc.
//
// According to the DataFlex documentation, the accuracy
// of the set_timer command is dependent on the operating
// system.  The timer has a documented resolution of 1/100th
// of a second but "most operating systems do not return
// time intervals with this much accuracy." [DAC 
// documentation]
//
// This program is designed to test the minimum resolution
// that the set_timer command uses on a particular operating
// system.
//
// How to use:
//    dfrun testtime {interval}
//    where interval is a number, from 1 to 100, that
//    represents the delay (in 100ths of a second) that
//    should be used in the set_timer command.  If 
//    interval is not provided, the default value of 1
//    is used.
//
// How to test:
// 1)  First, run "dfrun testtime" to see what happens.
//     The screen will clear and a message will tell you
//     to press any key to stop the test.  Meanwhile, a
//     number will start displaying.  This is the number
//     of times per second that the "ping" procedure is
//     being called.  
// 2)  To see how many times, on your operating system,
//     the timer is called with larger periodic intervals,
//     start the test with "dfrun testtime #" where #
//     is some number from 1..100.  "dfrun testtime 50",
//     for example, will generally have testtime called
//     twice per second (every 50/100ths = 1/2 second).
// 
// Using the default period value of 1 (to time the fastest
// resolution available), on one of my 
// Windows 2000 desktop computers, I get results of
// 18 or 19 times per second, which suspiciously corresponds
// with the CPU's event timer that fires every 1/18.1 (or so)
// seconds.
//
// On another machine also running Windows 2000, the results
// I get are consistently 1 time per second.  That's a
// significant difference!
//

use timer

integer testdelay   // User specified set_timer delay 
cmdline testdelay

// testdelay defaults to 1 if it wasn't specified by the user
if testdelay eq 0 move 1 to testdelay 

date today
integer hour minute second

integer last_pingsecond   // What second was last pinged?


// How many pings were there since the last second?
integer pings             

move 0 to pings

// This procedure was purposely kept very small, and uses
// global variables to reduce its initialization and run time.
procedure ping
  sysdate today hour minute second

  if last_pingsecond ne second begin   
    // we have a new timeframe -- tell what happened in the
    // previous timeframe.
    show pings " pings = " (1.0/pings) " seconds per ping"
    // This next line overwrites any residual characters
    // that result from a differnt number of decimal
    // places in the (1.0/pings) calculation.
    showln "                               "
    move 0 to pings
    move second to last_pingsecond
  end
  increment pings
end_procedure

// This is the timer being tested.  
set_timer blink periodic desktop ping testdelay

show   "Testing with a set_timer delay of " testdelay 
showln "/100ths of a second."
showln "Press any key to stop the test."
string akey 1
inkey akey

The output for this program on one of my Windows 2000 desktop machines looks like this:

Testing with a set_timer delay of 1/100ths of a second.
18 pings = 0.05555555 seconds per ping

On this computer, the results sometimes display 19 pings, but most of the time 18 pings appears. This suspiciously corresponds with the CPU's event timer that fires every 1/18.1 (or so) seconds.

Amazingly, the exact same program, when run on a different Windows 2000 desktop, gives these results:

Testing with a set_timer delay of 1/100ths of a second.
1 pings = 1 seconds per ping

Wow! That's an amazing difference considering that both machines are running the same operating system. The difference is probably due to the differences between the BIOS used by each motherboard.

Summary:

Because of the limitations of the SET_TIMER command (it only works while in a keyboard wait loop, its documented best resolution is only 1/100th of a second, the timing is inconsistent between two machines even with the same operating system), the SET_TIMER is probably a poor choice for most event timing. The one redeeming virtue that makes SET_TIMER practical to use is that it does execute during a keyboard wait loop.

In a GUI style program, using SET_TIMER to time an event during a keyboard wait loop might be a viable choice. In a procedural or non-GUI style program, the INKEY command can be used to time the event in a keyboard wait loop. In that case, use the microsecond timing technique described on page 5 to determine how long an event took.

Microsecond timing is incredibly accurate -- and some may justifiably argue that it's too accurate if it's detecting the amount of time the operating system steals from the process.

When a hyper-accurate (40 microsecond) timing resolution isn't needed, consider using instead the techniques shown in the fourth page of this article, A Better Timer. The program in that article shows how to obtain consistent results when using SYSDATE or SYSDATE4 but at only a 1 second resolution.

Also, don't forget the Rules of Thumb when timing events on a computer. Don't let one faulty test that had an anomalous result influence your decisions about which algorithm to use. Repeat, repeat, repeat!

I hope that you enjoyed this article and learned something interesting about DataFlex and timing issues. Let me know if you liked it (or not). Your feedback will help guide me when writing future articles.

Curtis Krauskopf (email at )

Curtis Krauskopf is a software engineer and the president of The Database Managers (www.decompile.com). He has been writing code professionally for over 25 years. His prior projects include multiple web e-commerce applications, decompilers for the DataFlex language, aircraft simulators, an automated Y2K conversion program for over 3,000,000 compiled DataFlex programs, and inventory control projects. Curtis has spoken at many domestic and international DataFlex developer conferences and has been published in FlexLines Online, JavaPro Magazine, C/C++ Users Journal and C++ Builder Developer's Journal.

The Database Managers helps companies to:
  •  become more profitable
  •  grow their business
  •  fix programs that are behaving badly
  •  write new programs to solve business problems
  • do more with fewer resources
Email them at to find out how to make your company more successful.

Go Back to Page: 1 2 3 4 5

Go to DataFlex Tips

Copyright 2003-2010 The Database Managers, Inc.

 


Other Popular DataFlex topics at The Database Managers, Inc.:

DataFlex: Tips | Freeware | WebApp Server | Books | Links
Services | Programming | Contact Us | Recent Updates

Send feedback to: