andreas-kupries / critcl

Critcl lets you easily embed C code in Tcl. Online documentation at
http://andreas-kupries.github.io/critcl
Other
72 stars 19 forks source link

Loading critcl package slows all Tcl script execution #112

Closed cyanogilvie closed 2 years ago

cyanogilvie commented 3 years ago

Just doing a "package require critcl 3" slows execution of typical Tcl scripts by about 10%, and in some cases much more ([dict set foo bar baz] is about 50 % - 60 % slower). This is due to critcl.tcl enabling interp frame debug at load time, which, once enabled, can't be turned off in that interp. Since improving the performance of some Tcl script is a major use case for critcl I would argue that his is self-defeating and better left up to the script author to turn on if needed. This is demonstrated by:

package require Tcl 8.7

rename interp _interp
proc interp {op args} {
    switch -- $op {
        debug {
            # Uncomment this to go fast (by preventing interp frame debug from being turned on)
            #return
        }
    }
    tailcall ::_interp $op {*}$args
}

set script  {dict set foo bar baz}

# Prime
try $script

set ms  3000
puts "before: [set before [lindex [timerate $script $ms] 0]]"
package require critcl 3
puts "after:  [set after  [lindex [timerate $script $ms] 0]]"

puts [format "script:\n%s\nslowdown: %.2f %%" $script [expr {100.0 * $after/$before - 100}]]
andreas-kupries commented 3 years ago

Hi @cyanogilvie nice to hear from you (even if it is about an issue with one of the things I work on)

I suspect that is the fact that I am using critcl pretty exclusively in package mode leaking through. I.e. build the package ahead of time, and at runtime Critcl is not involved any longer. Versus you using it in compile & run mode, and this then affects not just building the code, but leaks into the using environment.

Thankfully this also points to a solution where I can have my cake (more precise locations when compilation fails) and eat it too (not affect the larger environment). IOW, activate interp frame debug only from package mode. It should be possible to do this by moving the relevant command out of the main critcl package into the application package, for that is a requirement for package mode. It can only be used from the critcl application.

Do you believe that this solution would meet your requirements also ? I will implement this now, and put on a branch/PR for you to evaluate.

andreas-kupries commented 3 years ago

PR is #113