| Page 6 Timing an Event in DataFlexby Curtis KrauskopfMeasuring 
                          the SET_TIMER ResolutionThe 
                          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: 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: 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: Email them at become more profitable grow their 
			business fix programs 
			that are behaving badly write new programs 
			to solve business problemsdo more with 
			fewer resources
  to find out how to make your company more successful. |  
                           
                            | Go 
                              Back to Page: 1 
                              2 
                              3 
                              4 
                              5 |  |  Go to DataFlex 
                          TipsCopyright 2003-2010 The Database Managers, Inc.   
 Other Popular DataFlex topics at The Database Managers, 
  Inc.: |