1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
Profiling with NSF
==================
NSF offers the following built-in options for profiling,
which apply to methods (all instance and per class methods
of XOTcl, NX, ...) and to nsf::procs.
Preliminaries:
--------------
- make sure nsf is compiled with "--enable-profile"
- if you are not sure, check the file config.log
in the source directory, where nsf was compiled.
You find a line looking like
$ ./configure ....
near to the top of the file. If the configure line does
not contain "--enable-profile", run the configure command
with "--enable-profile" added, then
make clean; make; sudo make install
- to check, if the version you are using is complied properly
check the global Tcl array ::nsf::config, e.g. with
$ nxsh
% parray ::nsf::config
Profiling:
----------
From nsf profiling supports
1) detailed profiling about a full run, or
2) selective profiling
Dtrace:
-------
Alternatively dtrace [2] can be used to obtain
profiling information from nsf (and Tcl as well)....
but this depends on the operating system support
(Solaris heritage).
=========================================================================================================
#
# Sample script and helper procs to show, how profiling/tracing works
# in NSF with the not widely advertised profiling support based on
#
# ::nsf::__profile
#
# Gustaf Neumann
#
package require nx
#
# Helper function for in-memory profiling
#
proc mini-profile {cmd} {
if {[nsf::pkgconfig get profile]} {
try {
nsf::__profile_clear
nsf::__profile_trace -enable true
uplevel $cmd
} on error {errorMsg} {
error $errorMsg
} finally {
nsf::__profile_trace -enable false
}
#
# The collected profile data contains:
#
# totalMicroSec: measured time since profile start
#
# overallTime: aggregated time from traces
#
# objectData list of lists, where every element contains
# {object class method} aggregated_time number_of_calls
#
# methodData list of lists, where every element contains
# {method class} {callerMethod callerClass} aggregated_time number_of_calls
#
# procData list of lists, where every element contains
# {proc aggregated_time number_of_calls}
#
# trace new-line separated entries containing call, exit, and time
#
lassign [::nsf::__profile_get] totalMicroSec overallTime objectData methodData procData trace
# Output profile data... or do something else with it...
#
puts "Profile Data:\n==================="
foreach v {totalMicroSec overallTime objectData methodData procData trace} {
set break [expr {$v eq "trace" ? "\n" : "\t"} ]
puts "$v$break[set $v]"
}
puts "==================="
} else {
puts stderr "NSF is not compiled with profiling support"
uplevel $cmd
}
}
nsf::proc bar {x:integer} {
return $x
}
nx::Class create C {
#
# Naive version of factorial
#
:public method fact {n} {
if {$n < 2} {
return 1
} else {
return [expr {$n * [:fact [expr {$n-1}]]}]
}
}
:public method foo {n} {
bar 1
return [:fact $n]
}
}
C create c1
#######################################################
# Plain run
#######################################################
puts "factorial of 6 = [c1 foo 6]"
#######################################################
# Run the same command with profiling,
# collect the profile data in memory
#######################################################
mini-profile {c1 foo 6}
puts "\nTrace profiling information to output"
puts "==================="
nsf::__profile_trace -enable true -dontsave true -verbose 1
c1 foo 6
nsf::__profile_trace -enable false
puts "==================="
#######################################################
# Define custom logger to handle e.g. trace output
#######################################################
proc ::nsf::log {level msg} {
puts stderr "MY-logger: $level: $msg"
}
puts "\nTrace profiling information to output (with extra logger)"
puts "==================="
nsf::__profile_trace -enable true -dontsave true -verbose 1
c1 foo 6
nsf::__profile_trace -enable false
puts "==================="
#######################################################
# Selective profiling and tracing
# Define custom debug commands
#######################################################
proc ::nsf::debug::call {level objectInfo methodInfo arglist} {
nsf::log Debug "MY call($level) - $objectInfo $methodInfo $arglist"
}
proc ::nsf::debug::exit {level objectInfo methodInfo result usec} {
nsf::log Debug "MY exit($level) - $objectInfo $methodInfo $usec usec -> $result"
}
#
# Select methods to be traced (could be also done with the
# flag "-debug" in the source
#
::nsf::method::property C fact debug true
::nsf::method::property C ::bar debug true
puts "\nSelective profiling (with extra logger, debug, and custom debug messages)"
puts "==================="
c1 foo 6
puts "==================="
|