How to clock routines which (should) go faster than 1 sec

From the basic routines in Axapta we only have the TimeNow() function which returns number of seconds since midnight. To measure something more exact than that, we either need to do an API call to getTickCount or to use the setTimeOut() function. This is a small demo on how to implement both such timers.

Example 1, using setTimeOut function:
First, add below lines to your form classDeclaration.

1
2
3
   int tmSecs;
   int tmCounter;
   int tmLastTime;

Second, add this new method to your form methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void updateTimer(boolean _restart=false)
{
    int t;
    ;
 
    // Start a cycle with the idle flag set to false
    this.setTimeOut(identifierstr(updateTimer), 1, false);
 
    t = TimeNow();
    if(_restart)
    {
        tmSecs = 0; tmCounter = 0; tmLastTime = t;
    }
 
    if(t == tmLastTime) // still same second since last call
        tmCounter++;
    else             // new sec, reset and count on next.
    {
        tmSecs++;         // if more than one,
        tmCounter  = 0; 
        tmLastTime = t;
    }
}

Then in your code there you want to clock something, first add this call before …

1
    this.updateTimer(true);

… and then this after …

1
    info(strfmt("%1 %2", tmSecs, tmCounter));

After each run you get a rather exact measure, at least it shows differences between your changes in code. After experimenting with this I noticed the counter is a bit unreliable, so measure differences between *several* runs, not just once.

Example 2, using the getTickCount function:
After I wrote this I got a tip from Björn Olievier at SysDictCoder.com to use an API call to getTickCount instead. When it comes to measure a specific scope of code, below example is much better. Still I leave first example above, since it also demonstrate other possibilities which could be executed at the same time as our current code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void FO_TestTicks(Args _args)
{
    InventTable localInventTable;
    int         tmBegin,tmEnd;
    ItemId      itemId;
    ;
 
    tmBegin = winAPI::getTickCount(); // start in milli-sec
    while select * from localInventTable
    {
        itemId = localInventTable.ItemId;
    }
    tmEnd = winAPI::getTickCount(); // stop in milli-sec
 
    info(strfmt("Time elapsed: %1 second(s)", 
                (tmEnd - tmBegin)/1000 ));
}

Last 5 posts in Development

2 thoughts on “How to clock routines which (should) go faster than 1 sec

  1. Interesting use of setTimeOut(). But with all function calls to updateTimer, I think there’s still a rather large overhead and measuring error, hence the unreliability you noticed.

    Have you considered using WinAPI::getTickcount()? It’s a wrapper around the Windows GetTickCount function which returns the number of milliseconds the system has been running. It’s what the Timer class in 3.0 uses.

  2. The getTickCount method is of course much better. Thanks for the tip, I will add an update to this later with that included.

    /Henrik

Leave a Reply

Your email address will not be published. Required fields are marked *