Nicholas Clark wrote: > On Wed, Nov 25, 2009 at 10:42:59PM -0700, karl williamson wrote: >> Oops, forgot to put the function in. >> karl williamson wrote: > >>> So, I tried it with NYTProf. As I expected (I had used DProf earlier), >>> the highest usage subroutine was my pure Perl version of >>> Scalar::Util::refaddr, reproduced below. A third of the total time was >>> spent in this routine. (This is required because miniperl doesn't do >>> dynamic loading, so refaddr is not available.) >>> >>> When I was writing mktables, I was under the impression that refaddr >>> would be brought into the core for 5.12. There was an agreement to that >>> effect, but I guess no one ever got around to actually doing it. >>> >>> When I run this under perl instead of miniperl, and change objaddr to >>> just return refaddr, the combination still takes quite a lot of time. If >>> refaddr were in the core would it be in-lined? > >> sub objaddr($) { >> # Returns the address of the blessed input object. Uses the XS >> version if >> # available. It doesn't check for blessedness because that would do a >> # string eval every call, and the program is structured so that this is >> # never called for a non-blessed object. >> >> return Scalar::Util::refaddr($_[0]) if $has_fast_scalar_util; >> >> # Get the package >> my $pkg = ref($_[0]) or return undef; >> >> # Change to a fake package to defeat any overloading >> bless $_[0], 'main::Fake'; >> >> # Numifying a ref gives its address. >> my $addr = 0 + $_[0]; >> >> # Return to original class >> bless $_[0], $pkg; >> return $addr; >> } >> >> I found that any overload in a class caused the numifying to fail if I >> did it in that class; hence the blesses are necessary. > > I have memory of comments being made on IRC about no overloading. Using it > avoids the need to rebless. With this patch: > > diff --git a/lib/unicore/mktables b/lib/unicore/mktables > index ee51608..b2624f0 100644 > --- a/lib/unicore/mktables > +++ b/lib/unicore/mktables > @@ -1133,17 +1133,11 @@ sub objaddr($) { > return Scalar::Util::refaddr($_[0]) if $has_fast_scalar_util; > > # Check at least that is a ref. > - my $pkg = ref($_[0]) or return undef; > - > - # Change to a fake package to defeat any overloaded stringify > - bless $_[0], 'main::Fake'; > + ref($_[0]) or return undef; > > # Numifying a ref gives its address. > - my $addr = 0 + $_[0]; > - > - # Return to original class > - bless $_[0], $pkg; > - return $addr; > + no overloading; > + return 0 + $_[0]; > } > > sub max ($$) { > > I find that on "my machine" the run time (with ./miniperl) goes down from 47 to > 38 seconds. That's pretty close to the run time with ./perl (and hence > real Scalar::Util::refaddr) of 35.5 seconds. Many thanks > > Technically, I think, this falls foul of a strict reading of the feature > freeze, as it's not a bug fix. Unless "it's too slow" is considered a bug. > Ah, but it isn't a new feature; I could argue that mktables isn't even a new feature, but no point; it met the deadline anyway. I'll submit a patch with your fix. I'm trying to keep mktables compatible with 5.8 in case a user wants to apply it; no object recompilations are needed. 'no overloading' is not a 5.8 feature, so I'll add something to redefine it when that pragma is not available. > Nicholas Clark >Thread Previous | Thread Next