'''`[http://tcl.tk/man/tcl/TclCmd/time.htm%|%time]`''' a [Tcl Commands%|%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 [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. [bll] 2018-2-21 And don't forget the classic issue with unix. Unix has very good disk buffering. The first time you execute a program, the files need to be loaded from the disk drive. The second time you run it, the files are fetched from the disk buffer. This can affect benchmarks and timing drastically. Always remember to run the timing twice, and report the stats from the second run.