in reply to Re: Space taken by a coderef
in thread Space taken by a coderef

I'm not sure there is practical utility. The first thing is that closures provide "hard encapsulation", where the only way to the internals of an object is through the interface. This comes at a small CPU hit, naturally.

My immediate thought is for flyweight objects that take more than one scalar's worth of info. Instead of using class-level parallel arrays to keep the info, I was thinking that, maybe, closures would be more memory-efficient. (This is over arrays or hashes.)

Now, yes, I know that optimizing for memory isn't necessarily a good thing, especially this early in the game. But, I just want to keep my options open and see what the comparison is.

An example of what I'm talking about would be:

sub new { my $class = shift; return undef if ref $class; my ($first, $second) = @_; my $self = sub { my $var = shift; my ($mode, $newval) = @_; if ($var == 0) { return $mode ? $first = $newval : $first; } elsif ($var == 1) { return $mode ? $second = $newval : $second; } return undef; }; bless $self, $class; return $self; }

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Replies are listed 'Best First'.
Re: Re: Re: Space taken by a coderef
by chromatic (Archbishop) on Jan 19, 2002 at 00:53 UTC
    Ahh, I see. In this case, Perl compiles the closure once and only needs one copy of the optree. It only has to attach to the lexical scope once for each unique closure created, so you'll have the cost of a scratchpad that holds $first and $second, as well as the cost of the lexical variables within the closure.

    It wouldn't surprise me if this were slightly more efficient than a hash, but you'd probably need to get up above five or six member variables before it pays off. You'll save a little bit on accessors, though, but that's probably just the cost of the optrees, and you can avoid that if you're clever.

      The cost of the lexicals within the closure (and the operations of assigning to them) can be avoided by using direct access to @_. *shrugs*

      How would I avoid the cost on accessors? What exactly is this optree you're talking about? Can I affect the optree after creating the closure?

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        The optree is Perl's internal representation of your code -- bytecode, in Parrot terms. Closures are nice because they all share the same opcodes. (To simplify things perhaps past the point of correctness :), a cv, or code value, is a struct with a pointer to the optree for the function. There's also a pointer to the lexical scratchpad that holds enclosed variables.) The only difference is the lexical pad to which the closure is attached.

        If you had a dozen accessors, you could write a dozen subroutines with individual optrees, or you could autogenerate them and use 1/12th the memory with one shared optree and closures.

        If you want to modify the optree, you'll have to use the B:: modules and learn a lot more than I know at the moment, or have a lot of luck. :)