Index: README.profile =================================================================== diff -u --- README.profile (revision 0) +++ README.profile (revision e40a0652c229cf6ff5ddc1557c4dfc3055acce24) @@ -0,0 +1,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 "==================="