From: SourceForge.net <no...@so...> - 2009-10-20 16:17:27
|
Patches item #2868499, was opened at 2009-09-28 01:57 Message generated for change (Comment added) made by ferrieux You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=310894&aid=2868499&group_id=10894 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: TIP Implementation Status: Open Resolution: None Priority: 5 Private: No Submitted By: Alexandre Ferrieux (ferrieux) Assigned to: miguel sofer (msofer) Summary: TIP #348: Substituted errorStack Initial Comment: Here is a crude but functional implementation of TIP #348. The variable ::errorStack, comes to life when defined (which is not the case by default, to avoid any performance hit). While unwinding, it is populated by substituted argslists as described in the TIP. It is automatically reset (to the empty list) whenever ::errorInfo is. (But this leaves it enabled. To disable it, unset it.) (Among crudities: uses ::errorStack instead of ::tcl::errorStack, doesn't pay attention to code style, no test cases. Also, it inserts two fields in the private interp structure, right in the middle, not at the end. ABI hazard, don't forget to 'make clean' after applying ;-) ---------------------------------------------------------------------- >Comment By: Alexandre Ferrieux (ferrieux) Date: 2009-10-20 18:17 Message: Attaching a new patch, errorstack2.patch, fulfilling Joe's request of [info errostack ?interp?] and [dict get $d -errostack]. I left the ::tcl::useErrorStack control variable for perf measurements: 0 --> pristine HEAD 1 --> just [info errorstack] 2 ---> adds options dict entry -errorstack Note the implementation still uses ckalloc-based Tcl_NewListObj for argslist, pending proof that optimization is needed. Here are the figures: Case: Ten-fold catch ladder use=0 -> 74.7924 microseconds per iteration Case: Ten-fold catch ladder use=1 -> 76.7888 microseconds per iteration Case: Ten-fold catch ladder use=2 -> 77.1977 microseconds per iteration Case: Single Catch with opt dict use=0 -> 19.2613 microseconds per iteration Case: Single Catch with opt dict use=1 -> 19.7608 microseconds per iteration Case: Single Catch with opt dict use=2 -> 20.2815 microseconds per iteration with code: for {set i 1} {$i<10} {incr i} { proc f$i x "f[expr {$i+1}] \$x" } proc f10 x {error F10:$x} proc boo {} {error BOO} proc catchloop {} { for {set i 0} {$i<100000} {incr i} { if {[catch boo m d]} continue } } foreach {mm ss} { "Ten-fold catch ladder" {catch {f1 12}} "Single Catch with opt dict" {catch boo m d} } { foreach v {0 1 2} { set ::tcl::useErrorStack $v puts "Case: $mm use=$v -> [time $ss 10000]" } } ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2009-10-05 10:12 Message: Complete with test cases now. ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2009-10-05 02:46 Message: Mostly done. - now the var is ::tcl::errorStack and the flag is ::tcl::useErrorStack - zero overhead when ::tcl::useErrorStack is 0 (default) - uses a read trace to postpone var machinery until real use - uses an optimized in-place lappend/reset to keep the list intrep as much as possible (just as fast as the linked list approach IMO) TBD: test cases. ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2009-09-29 01:00 Message: First slight improvement: explicitly skip iPtr->rootFramePtr, like in [info level $n], since the root frame will always have argc==0. This removes the parasitic {} always found at the end of ::errorStack, and also an extra one generated by [tailcall] and [coroutine]. Next improvements planned: (1) make the on/off switch more efficient by using a linked boolean var rather than the existence of ::errorStack which costs a hash lookup when negative. (2) make the list building slightly more efficient by using a backbone of Tcl_Obj as Cons'es (linked list), and turning it into a Tcl list only in a read trace attached to ::errorStack (instead of directly lappending as is currently the case. This construction is wasted in caught, expected exception handling where the errorStack is not used). (3) proper ::tcl namespace + test cases. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=310894&aid=2868499&group_id=10894 |