Time

Difference between version 29 and 30 - Previous - Next
'''`[http://tcl.tk/man/tcl/TclCmd/time.htm%|%time]`''' a [Tcl Commands%|%built-in] Tcl command, repeatedly executes a [script], and reportselapsed time. See also the newer http://www.tcl-lang.org/man/tcl8.6/TclCmd/timerate.htm%|%timerate%|% command which aims to fix some deficiencies of the [time] command.


** 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 [Changes
in Tcl/Tk 8.5%|%8.5], elapsed time has sub-microsecond resolution,  with
accuracy depending on the timers available from the [operating system%|%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
[https://www.youtube.com/watch?v=-5wpm-gesOY%|%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 [http://www.faqs.org/rfcs/rfc868.html]
[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.
<<categories>> Tcl Commands | Arts and crafts of Tcl-Tk programming | Performance | Internet