develooper Front page | perl.perl5.porters | Postings from November 2009

Re: Speeding up mktables; NYTprof

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
November 26, 2009 07:43
Subject:
Re: Speeding up mktables; NYTprof
Message ID:
20091126154326.GN2582@plum.flirble.org
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.

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.

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About