namespace eval timing {array set t {}} proc timing args { set template { set t [time {set res [uplevel 1 ::timing::@here@ $args]}] lappend ::timing::t(@here@) [lindex $t 0] set res } foreach procname $args { rename $procname ::timing::$procname proc $procname args [string map [list @here@ $procname] $template] } }#-- This produces a string with the results, in sorted order:
proc timing'get {{name *}} { set res "" foreach i [lsort [array names ::timing::t $name]] { set times $::timing::t($i) append res "$i : [llength $times] times, [mean $times] usec\n" } set res }#-- For heavy use, better use a looping mean - see Elegance vs. performance
proc mean list {expr ([join $list +])/double([llength $list])}#-- Now testing (I let them all wait a while so time for certain gets non-zero):
proc foo args {after 10; return 42} proc unbraced {x y} {after 10; expr $x+$y} proc braced {x y} {after 10; expr {$x+$y}} timing foo unbraced braced foreach i {1 2 3 4 5 6 7 8 9 10} {foo; unbraced 17 4; braced 17 4} puts [timing'get]#----- which shows on my machine:
braced : 10 times, 15500.0 usec foo : 10 times, 15700.0 usec unbraced : 10 times, 15700.0 usecThe examples are of course over-simplified, and their measured times should not be taken too serious :^)
Category Debugging | Arts and crafts of Tcl-Tk programming