As a developer you might need a timer in your database. In that case you might find this feature helpful. You can create timer, as many as you like. Use them for benchmarks, to log import and export times, or to keep track of user log-in times.
Each timer works like a little stopwatch. You can …
- start it,
- stop it,
- restart/stop it again,
- read the elapsed time,
- and reset/remove it.
This is accomplished with custom functions and a global variable:
- timer( name; action )
- param( key; value )
- param.get( key; params )
- param.delete( key; params )
CF param.delete( _key; _params )
The custom function timer uses three functions from my library. I have described two of them – param and param.get – already in the post Manage Parameters. The third – param.delete – is used to remove a parameter from the parameter string.
The function expects two function parameters, first the name of the parameter (key), then the parameter string (params).
Function param.delete( _key; _params )
If( IsEmpty( params ) or IsEmpty( key ); ""; // Else Let( [ _params = ¶ & params; _key = ¶ & Substitute( key; [ "="; "^=" ]; [ ¶; "\¶" ] ) & "=="; _start = Position( _params; _key; 1; 1 ) ]; If( _start = 0; params; // Else Let( [ _end = Position( _params; ¶; _start + Length( _key ); 1 ) ]; If( _start = 1; Middle( params; _end; 1000000 ); // Else Left( params; _start - 1 ) & Middle( params; _end; 1000000 ) ) ) ) ) )
CF timer( name; action )
The timer function also expects two parameters, first the name of the timer, then the action to be performed with the timer.
The name of the timer can be an empty text; the default timer is then used.
Action can be one of the following values:
- START – Initialize the timer with the current time. If the timer is already running, it will reset and re-initialize the timer.
- STOP – Stop the timer.
- DELETE – Delete the timer. DEL and REMOVE do the same thing.
- READ – Return the elapsed time of the timer.
Actual, every call of the function will return the elapsed time. This allows to ‘stop’ the timer multiple times. With each STOP the function returns the new elapsed time. Also, it does not matter, whether you use READ or something like GET to read the time. In both cases the function will return the elapsed time.
Function timer( _name; _action )
Let( [ _name = If( IsEmpty( _name ); "
"; name ); _action = Upper( _action ); _now = Get( CurrentTimeStamp ); _timer = param.get( _name; $$timer ); _start = param.get( "START"; _timer ); _stop = param.get( "STOP"; _timer ); _stop = If( IsEmpty( _stop ); _now; _stop ); _diff = If( IsEmpty( _start ); ""; GetAsTimestamp( _stop ) - GetAsTimestamp( _start ) ); _timer = Case( _action = "START"; param( "START"; _now ); _action = "STOP" and IsEmpty( _start ); param( "START"; _stop ) & param( "STOP"; _stop ); _action = "STOP"; param( "START"; _start ) & param( "STOP"; _stop ) ); $$timer = Case( _action = "START" or _action = "STOP"; param.delete( _name; $$timer ) & param( _name; _timer ); _action = "DEL" or _action = "DELETE" or _action = "REMOVE"; param.delete( _name; $$timer ); $$timer ) ]; _diff )
Using the Timer
You may use the timer in any script. First, set a dummy variable to start the timer. Then do the steps you want to benchmark. At the end, set a variable again to stop the timer. This variable will have already the elapsed time. But you can read the timer at a later time again, perhaps in the Data Viewer.
Set Variable [$_; Value:timer( "benchmark 1"; "START" )] ... Script steps to be benchmarked ... Set Variable [$_; Value:timer( "benchmark 1"; "STOP" )]
You can have as many timers running as the same time as you like. The FileMaker function Get( CurrentTimestamp ) is only exact to the second. Therefore, you cannot time shorter intervals.
Because this function uses global variables, a timer is only visible within the file it was created.