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

Re: Speeding up mktables; NYTprof

Thread Previous | Thread Next
From:
karl williamson
Date:
November 26, 2009 09:36
Subject:
Re: Speeding up mktables; NYTprof
Message ID:
4B0EBC85.2050702@khwilliamson.com
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


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