I asked some questions earlier in the week about ns_adp_parse. I've done some research in an attempt to answer them myself, and am presenting my result.

Does the current working directory change in the same way?
It doesn't appear to.

How is out-of-band data handled (cookies, etc.)?
Seems to be handled separately, so that cookies written in parsed code still get set even if the result of the parse are tossed.

How is control data handled (setting encoding, etc.)?
I am assuming the same holds true here as does for cookies.


How are return codes handled (returning a page not found, etc.)?
I haven't tested the various return codes yet, since most of them won't be applicable in the situations I have in mind. It's worth looking into them for information purposes, though. The codes I can think of that should be looked into are:
  • Normal Tcl exception conditions
  • The results of ns_adp_abort, ns_adp_break, ns_adp_return

General observations:
There are two different aims I had in looking into ns_adp_parse. The first was making sure it wasn't too slow to use. The second was to allow my pages to parse "pieces" of the page, and then discard all the output for a given piece if any errors were thrown in it's generation. The second goal definitely seems to be accomplished, if we ignore out-of-band data. Since such data would need to be accounted for in any other way I tried to accomplish the goal, I don't consider this an issue.

When it came to timing how fast ns_adp_parse was, I found several facts that caught me slightly off guard at first. Thinking them through, I believe they all make sense. To give some detail, I timed "content generation" for several different approaches:

  • Direct Output - This was a normal include file, with some static html and some ns_adp_puts.
  • Puts Output - This was an include file where all it's output was marshaled into a variable (appended), and ns_adp_puts at the end.
  • Include Return - This was the same as "Puts Output", but using ns_adp_return to return the data to the caller so that they can choose to output it or not.
  • Proc Return - Similar to the above, but the html is generated in a Tcl proc instead of an include file.
  • Parser - The most ignorant implementation using ns_adp_parse... open file, read file, close file, parse text
  • Parser 2 - The same as the above, but with the open/read/close steps removed. Effectively, assuming we cache file contents once we read them
  • Parser BC - This implementation used a static block of text that was parsed whose only function was to ns_adp_include a file. The reason for this will be explained below.

The timings for the above methods varied slightly, but generally came out in the following order and times:

Name          Milliseconds  Description
Proc Return:    101.490     tcl proc returning html
Direct Output:  172.705     normal ADP programming
Puts Output:    203.930     marshaled output, single ns_adp_puts
Include Return: 204.460     ns_adp_include returning html
Parser BC:      207.200     ns_adp_parse, with byte compiling
Parser 2:       459.955     ns_adp_parse, no file load overhead
Parser:         606.320     ns_adp_parse

As can be seen, the Tcl proc is the fastest method by a considerable margin. This is understandable, due to it being a byte compiled object command.

The normal adp programming method was the second fastest, which was somewhat of a surprise to me. I was led to believe that it would be slower than the Puts Output method.

The Puts Output and Include Return methods came in around the same speed, though they were almost always in the same order presented above. I have been told that ns_adp_include byte compiles it's input but it, and the byte compiled result), are string based commands, rather than Object based. I believe this explains the slowdown involved in using them.

The Parser and Parser 2 methods came in remarkably slow. This surprise me until I realized that the ns_adp_parse command works much like eval in that it doesn't byte compile it's input.

The Parser BC command was written in an attempt (which was successful, I believe) to use ns_adp_parse, but still gain the speed benefits of byte compiling. Since we are reading our content from a file, we could minimize the amount of code that needed to be parsed each time. The implementation used for this method was simply:

proc ns_adp_parse_file {filename args} {
    set script "<% ns_adp_include $filename $args %>"
    return [ns_adp_parse $script]
}

Overall, I'm fairly happy with the results of Parser BC. I would think it would be possible to gain even further benefits if it were implemented in C (like ns_adp_parse and ns_adp_include). Additionally, if they are not currently, I think all 3 of them would benefit from being implemented as object commands as well as generating object based command byte codes.

My apologies for being so long winded. I asked the questions originally, but I thought others might find my conclusions to be useful.

Rob Seeger

-- AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to <[EMAIL PROTECTED]> with the body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: field of your email blank.



Reply via email to