Time

time a built-in Tcl command, repeatedly executes a script, and reports elapsed time.

Synopsis

time script ?iterations?

Description

time executes script one time, or optionally, iterations times, and reports the average elapsed time per iteration. Since Tcl version 8.5, elapsed time has sub-microsecond resolution, with accuracy depending on the timers available from the OS.

Example:

time {myCommand $arg1 $arg2} 1000

, which executes the script 1000 times, and returns a list like this:

 123456 microseconds per iteration

More iterations increase the precision of the returned value, at the cost of longer execution of time.

You can measure the runtime of a lengthy script with the following pattern:

set t0 [clock clicks -millisec]
...
...
puts stderr "[expr {([clock clicks -millisec]-$t0)/1000.}] sec" ;# RS

kbk, Tcl's own wizard of speed and time, has done all the work to ensure that Tcl accounts for time correctly so you don't have to .

A stabilized timing helper

DKF: It's not always easy to pick a good number of iterations to run the timing script for. This script picks a balance by trying to use the number of iterations that would take about 2 seconds (subject to it being a minimum of 500 iterations)

Explanation: The script first tries to factor out the compilation time, then does an initial timing run to estimate the number of iterations for the main run.

proc measure args {
    set it [expr {int(ceil(10000./[lindex [time $args] 0]))}]
    set it [expr {int(ceil(2000000./[lindex [time $args $it] 0]))}]
    while {$it < 500} {set it 500}
    lindex [time $args $it] 0
}

Use it like this:

measure theProc arg1 arg2...

Adapting to take a single script argument instead is trivial.

Novel Uses of Time

Even when you're not interested in the timing, you can use time as a simple control structure for loops:

time {puts Hello} 5

instead of

for {set i 0} {$i<5} {incr i} {puts Hello}

(MS voip in the Tcl chatroom 2005-03-03, brought here by RS)

sergiol

I use this approach as a code shortener, when I am doing code golf, as I state in https://codegolf.stackexchange.com/a/126236/29325 with a GOTCHA: « Sometimes it is worth to use time {script} n where n is the number of iterations instead of a normal while or for loop. Although time's purpose is not looping, the achieved effect is the same.

I made changes recently to my own answers following this direction.

UPDATE: I've just discovered an easy to fall pitfall: You can not replace a for or a while by a time block, if it contains a break or a continue. »

System Timings

LV: Sometimes users ask how to get a tcl program's time in terms of real/user/system, similar to how they would use the ksh built in time command. The command documented on this page doesn't provide information of that granularity. Does anyone know of alternative methods?


AMG, adapted from an email by MS:

"time has more looping overhead than a script version! See below for proof."

proc f {} {}

proc a {} {
    set n 100000
    puts [time f $n]

    set c $n
    incr c
    set start [clock microseconds]
    while {[incr c -1]} {
        f
    }
    set end [clock microseconds]

    puts "[expr {($end - $start)/double($n)}] microseconds per iteration"
}

a

On my machine (WinXP, Tcl 8.6b1.2), this produces the following times:

3.78325 microseconds per iteration
1.62831 microseconds per iteration

f is run 100,000 times, both by time and by while/incr. Strangely enough, it takes time more than twice as long as while to do this. That makes no sense. Maybe time is recompiling the script f each time. But, how long can it take to compile a script that's only one character long???

See Also

How to measure Performance
Additional info - but no obvious examples.

Disambiguation

Another use of the word time is as a network protocol for the transmission of time data - see RFC868 [1 ] NTP is a more sophisticated protocol, but the time protocol does a simple job simply.

In yet another different use of the word time, LV asks "Has anyone written a time chooser similar to the date chooser widgets written elsewhere on the Wiki?" Larry refers to A little date chooser and An i15d date chooser.

You might like to check out: timeentry and timefield.


roba - 2018-02-21 05:18:23

RE: loop vs time: I ran with f {} {after 1}. The time was about 1.1 ms, and it was randomly longer in the time command or the loop, there was no real difference. So possibly in the loop the f{} proc was optimized out.


arjen - 2018-02-21 08:08:27

You should be aware that such timings are at the mercy of the underlying operating system. Even with real-time OSes time delays are not always precise. Therefore: use sufficiently large intervals, so that completely random variations that you have no control over do not influence the results too much.

KPV - 2018-02-22: I like the counterintuitive advice of running a test several times and reporting the shortest time. The reason being is this is the result that most closely resembles the true timing with the least amount of OS noise.