Forum OpenACS Q&A: nsprofile vs. Eric's tclprof

Posted by Andrew Piskorski on
Well, I meant to post further information on nsprofile and Eric Lorenzo's new tclprof module, but never got around to it, so let me try to remedy that now: I used both nsprofile and tclprof briefly. I did not review the code of either in any detail, but I did take a quick look. Here's what I learned, and my thoughts for further work:

nsprofile can only instrument a single thread at a time, and it's data output formatting is very primitive. It will work for any one thread though, you just have to stick in explicit 'profile on' and 'profile off' Tcl commands. Tclprof, on the other hand, will automagically profile stuff in many different threads at once, and present the results nicely, but as the code stands today, it only works for connection threads.

In my case, I was specifically interested in profiling Tcl code in a single long-running detached thread. My needs were simple and very specific, so I just used nsprofile, since it supported my situation out of the box while tclprof did not.

However, tclprof appears to be more sophisticated than nsprofile, and is definitely better documented. Going forward, I would first compare the tclprof and nsprofile code to understand their strategies, if one codebase could benefit from the other, etc. I believe that at the time Eric wrote tclprof, he wasn't aware nsprofile existed, so AFAIK to date no one has done any such comparison.

Here are some specific comments on how I'd start improving tclprof:

First of all, the tclprof C functions should all be renamed to conform to AOLserver standards by prefixing them all with "Tp_" or something like that, but that's a very easy fix.

To make tclprof work for non-conn threads, first, ProfileTrace needs to be changed to not abort data capture when there is no Ns_Conn available. [I did that, easy.] Then, it looks like CleanupConnection is never run for non-conn threads, so the RequestTrace is never published into long-term storage, and thus www/index.tcl never shows anything for that thread. This is fundamentally why tclprof currently only works for conn threads. Since there's no logically usefull "end" to threads in general the way there is for a conn thread serving a particular page, the only obvious way I can think of to address that is to add tclprof start and stop Tcl commands, where 'tclprof stop' calls CleanupConnection. Then I could explicitly call 'tclprof start' and 'tclprof stop' in the Tcl code I want instrumented. [I didn't try that, but I think it should be straightforward.]

Eric mentioned that he was considering doing some magic so that ns_schedule threads would be automagically profiled, without you adding any sort of profiling "start" or "stop" commands into your scheduled jobs. That could be usefull, but I think it's mostly orthoganal to adding the "start" and "stop" Tcl commands that I suggest above. I would add the start and stop profiling commands first, which is simple and generally usefull, and only worry about more fancy automagical features later.

Also, one of Eric's design goals for tclprof seems to have been automagical profiling, where you just turn on the tclprof module, and everything (or most things) gets profiled without you changing a single line of your Tcl code - it does that for conn threads right now. This sort of automagical profiling sounds very cool, but it could also be very important to be able to turn off such automagical behavior, so you can use tclprof in a more targetted fashion, without impact on all the other running code that you're not interested in. For instance, imagine needing to run tclprof in a heavily loaded production server, in order to track down some specific performance problem that you can't easily replicate on your Dev server. If you already have a decent idea of where the problem code is, you probably don't want to take the (potentially very large) performance hit of running tclprof on everything.