If a nested subroutine refers to variables from an enclosing sub, it needs a pointer to the enclosing sub's stack frame.
Hmm. On reading your node I perused a bit of the literature on the subject, and I agree that you are generally correct. However to nitpick, if the outer sub is not visited from the inner, and we dont have to support threading then a single statically allocated pointer can be utilized without requiring additional room on the stack. When the outer sub is entered the pointer to the outer stack frame can be copied into the static memory, the inner sub knows the location of this memory (and the layout of the enclosing subs stack frame) at compile time, so can use it to access all extra data. Thus the overhead is reduced to a single "assignment", and not the expense of repeatedly passing the pointer on the stack.
I guess however that in the general case nested subs actually represent the implicit definition of a struct, and the passing of a pointer to that struct when the inner sub is called. Which means that the effect can be easily simulated in perl/c. However I think the elegance of the Pascal approach, as well as the encapsulation it provides is quite nice. You dont have to worry that the inner sub could be called incorrectly, as it is only visible to the outer. Nor do you have to worry about what your structs look like, the compiler handles it all transparently.
Correction: You don't have to pass a reference into the sub explicitly. Perl does it for you automatically. The mechanism for that might be a bit more efficient than using ordinary references, but that's not necessarily true beyond the current incarnation of Perl.
No correction actually. The point was that this reference doen't need to be placed on the stack. It can be resolved once and then never again. Contrast this to the same pointer being on the stack many many times, the space it occupies and the operations required to add and remove it from the stack. From this I think its safe to assume that the closure approach will probably outperform the stack based approach in virtually all non-trivial applications. (This assumes the cost of doing the single initialization is reasonably close to the cost of transfering the data on the stack, reasonably being up to several times slower. An assumption I dont think is particularly unreasonable.) Maybe ill throw some benchmarks together to do a careful analysis of the costs involved (under the currently available version of perl.)
Anyway, interesting points here. Thanks.
---
demerphq
|