Re^2: private recursive subroutines
by ambrus (Abbot) on May 11, 2007 at 09:34 UTC
|
In fact, it was diotalevi who taught me that my $f; $f = sub { ... &$f(...) ...}; leaks memory but the Y-combinator version my $g = sub { my $s = shift; ... &$s($s, ...) ... }; my $f = sub { &$g($g, @_) }; does not.
That was when I showed him the Y-combinatored version of a function for pureness (no side-effects). I didn't really need that because the function was global so I could have used side-effects (the memory leak wasn't an issue because it's a garbage-collected language). At that time, I didn't know that it has a practical application in perl because of the reference counting. You can find that implementation here: t2n.olv (source), t2n.pl (compiled to prolog), t2n.sml (compiled to sml), olvashato/ (link to all files).
Btw, diotalevi also claimed that this memory leak issue is described somewhere in Higher Order Perl, but I couldn't find it in that book. I'd be greatful if anyone can point me to the exact place.
| [reply] [d/l] [select] |
|
| [reply] |
|
That's wierd, because I thought there was no way to fix this bug without a different garbage collector.
On the other hand, I hope that the my $x; sub { sub { $x } } bug will be fixed by p5p, though I know nothing of its technical details.
| [reply] [d/l] |
|
|
|
Re^2: private recursive subroutines
by clinton (Priest) on May 11, 2007 at 09:46 UTC
|
local *foo= sub {
my ($param)= @_;
do { something };
foo($param);
};
... On the other hand it spoils the method cache which can cause a general slowdown for OO.
demerphq, would you mind explaining this a bit?
- How does the method cache work?
- Which part of the above spoils it?
- And what effect does it have on the cache?
thanks
clint
| [reply] [d/l] |
|
From my limited understanding, the method cache allows Perl to remember to which function a method call resolves so it doesn't have to traverse @ISA every time.
Changing the symbol table clears the cache. the value of *foo changes twice in the snippet in your post, the explicit assignment and the implicit assignment at the end of local's scope.
$o->method(); # Normal (first call)
$o->method(); # Faster due to cache
*foo = sub {};
$o->method(); # Normal (cache cleared)
$o->method(); # Faster due to cache
| [reply] [d/l] [select] |
|
Thanks, this is pretty much the response I would have made. The only thing I'd add is that as far as I understand things Perl 5.10 wont pay the same global penalty, rather the penalty will be restricted to the package or method itself, although I'm not sure which. This a side effect of Brandon Black's MRO patch for adding C3 style method resolution support to Perl.
---
$world=~s/war/peace/g
| [reply] |
|
|
|
|
ok - but that hit is taken when the sub is inserted into the symbol table. Assuming you don't every redefine the sub, you can use it without messing with the method cache, no?
| [reply] |
|