develooper Front page | perl.perl5.porters | Postings from March 2011

Re: [perl #82110] Still "keys" performance regression between 5.10.1and 5.12.3-RC1

Thread Previous | Thread Next
From:
demerphq
Date:
March 12, 2011 04:51
Subject:
Re: [perl #82110] Still "keys" performance regression between 5.10.1and 5.12.3-RC1
Message ID:
AANLkTi=p4SZCSPo1vPWSOvuy+8P28uvvvNbqdC1U=3Rz@mail.gmail.com
On 10 March 2011 18:04, Dave Mitchell <davem@iabyn.com> wrote:
> On Sun, Feb 06, 2011 at 01:07:25PM -0800, Father Chrysostomos via RT wrote:
>> On Tue Jan 18 06:53:20 2011, davem wrote:
>> > On Sun, Jan 16, 2011 at 01:28:11PM -0800, Father Chrysostomos via RT
>> wrote:
>> > > An expression like ‘my @array = ...’ might also reference @array on the
>> > > right hand side (if named subroutine closes over @array and its return
>> > > value is on the rhs), so the no-common-vars optimisation is disabled for
>> > > ‘my @array =’.
>> >
>> > But we should be able to tell whether the lexical is closed over by its
>> > reference count:
>> >
>> > $ p -MDevel::Peek -we'my $x; Dump $x'
>> > ALLOCATED at -e:1 for padsv (parent 0x0); serial 1763
>> > SV = NULL(0x0) at 0x2171f80
>> >   REFCNT = 1
>> >   FLAGS = (PADMY)
>> >
>> > $ p -MDevel::Peek -we'my $x; Dump $x; sub f {$x+1}'
>> > ALLOCATED at -e:1 for padsv (parent 0x0); serial 1763
>> > SV = NULL(0x0) at 0x283ef90
>> >   REFCNT = 2
>> >   FLAGS = (PADMY)
>>
>> At compile time, the OPpASSIGN_COMMON flag is set when the list
>> assignment is compiled. If the list assignment comes before the
>> subroutine that closes over the lexical, it’s not possible to know at
>> that time.
>> It’s not possible to use a reference count in pp_aassign, either,
>> because the stack is not reference-counted. (I tried that and got an
>> incredible speed-up, but ($a,$b)=($b,$a) stopped working.)
>
> And thinking further, you can get this behaviour without a closure too:
>
>    my $r;
>  again:
>    my @x = @$r; # *** common assignment on 2nd attempt!
>    @x = (1,2,3);
>    $r = \@x;
>    goto again unless $i++;
>
> So I think this assignment is correctly pessimised, and shouldn't
> be regarded as a bug.
>
> I'll close the ticket.

Am I right in understanding that our position is that a 30% slowdown
in "my @array= list " is an acceptable cost to make code like this:

     my $r;
again:
     my @x = @$r; # *** common assignment on 2nd attempt!
     print "@x\n";
     @x = (1,2,3);
     $r = \@x;
     goto again unless $i++;

work correctly and not result in "semi-panic: attempt to dup freed
string at /tmp/b.pl line 2." type errors?

I personally do not think that this is so clear cut, given that they
can do this:

     my $r;
again:
     my @x;
     @x = @$r; # *** common assignment on 2nd attempt!
     print "@x\n";
     @x = (1,2,3);
     $r = \@x;
     goto again unless $i++;

And have it work correctly?

I have not fully understood FC's closure case properly, so maybe this
is an easier trap to fall into than I think, but right now I'm
thinking this is a pessimisation that is much akin to make $1 "safe"
after a //g in scalar context, a case where we decided that simply
saying "don't do that" was better than making every //g match slower.

IOW, I'm not sure that sacrificing performance on a very common
construct to make what seems to me to be a pretty unusual edge case
work properly is a good trade off especially given there is an easy
work around.

While I don't think id go so far as to say we should actually choosing
speed over correctness is right here, I have to admit I'm tempted, and
do think at the very least we should keep this bug open.

cheers,
Yves


-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

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