| [ Team LiB ] |
|
Performance TuningThe time command measures the execution time of a Tcl command. It takes an optional parameter that is a repetition count:
time {set a "Hello, World!"} 1000
=> 28 microseconds per iteration
If you need the result of the command being timed, use set to capture the result: puts $log "command: [time {set result [command]}]" An extensive benchmark suite that compares various Tcl versions is available at: Time stamps in a LogAnother way to gain insight into the performance of your script is to generate log records that contain time stamps. The clock seconds value is too coarse, but you can couple it with the clock clicks value to get higher resolution measurements. Use the code shown in Example 13-1 on page 185 to calibrate the clicks per second on your system. Example 13-13 writes log records that contain the current time and the number of clicks since the last record. There will be occasional glitches in the clicks value when the system counter wraps around or is reset by the system clock, but it will normally give pretty accurate results. The Log procedure adds overhead, too, so you should take several measurements in a tight loop to see how long each Log call takes: Example 13-13 Time Stamps in log records
proc Log {args} {
global log
if [info exists log(file)] {
set now [clock clicks]
puts $log(file) [format "%s (%d)\t%s" \
[clock format [clock seconds]] \
[expr $now - $log(last)] \
[join $args " "]]
set log(last) $now
}
}
proc Log_Open {file} {
global log
catch {close $log(file)}
set log(file) [open $file w]
set log(last) [clock clicks]
}
proc Log_Flush {} {
global log
catch {flush $log(file)}
}
proc Log_Close {} {
global log
catch {close $log(file)}
catch {unset log(file)}
}
A more advanced profile command is part of the Extended Tcl (TclX) package. The TclX profile command monitors the number of calls, the CPU time, and the elapsed time spent in different procedures. The Tcl CompilerThe built-in Tcl compiler improves performance in the following ways:
The previous expression is not fully defined until runtime, so it has to be parsed and executed each time it is used. If the expression is grouped with braces, then the compiler knows in advance what operations will be used and can generate byte codes to implement the expression more efficiently. The operation of the compiler is essentially transparent to scripts, but there are some differences in lists and expressions. These are described in Chapter 54. With lists, the good news is that large lists are more efficient. The problem is that lists are parsed more aggressively, so syntax errors at the end of a list will be detected even if you access only the beginning of the list. There were also some bugs in the code generator in the widely used Tcl 8.0p2 release. Most of these were corner cases like unbraced expressions in if and while commands. Most of these bugs were fixed in the 8.0.3 patch release, and the rest were cleaned up in Tcl 8.1 with the addition of a new internal parsing package. The internal compiler continues to improve over time, with 8.4 extending the core instruction table to significantly improve performance over previous versions. |
| [ Team LiB ] |
|