Re: DAVEM TPF grant#2 report #156,#157

(this report covers two weeks)

I spent the bulk of my time over the last two weeks sorting out
infrastructure for ops which are called in boolean context.

Currently PADHV and RV2HV ops are flagged specially if they are not only
used in scalar context, but where the result they return will only
ever be used as a boolean value; for example 'if (%h) {...}'

This was originally done since a hash in scalar context returned a bucket
usage ratio, which became expensive to calculate when we no longer
stored the bucket occupancy count with each hash.

In 5.25.x we've changed it so that in scalar context it now only returns a
key count, which is always known and doesn't need to be calculated on the
fly. But it can still be quicker to return just a boolean value in
these cases rather than an integer.

My work took this special-case boolean context detection code in the
peephole optimiser, and improved it so that:

 * it fixes a bunch of bugs - e.g. if (!%h) {...} wasn't recognised as
   boolean;
 * it expands the number of situations that are recognised as boolean
   context, such as grep:  e.g. grep %$_, @AoH;
 * it adds a reasonably comprehensive set of tests for checking that ops
   have been flagged as boolean under various boolean scenarios;
 * it allows other ops to be easily added to the boolean detection in the
   optimiser; and to the test suite.

I've also tweaked RV2HV so that in the negative case it just returns
&PL_sv_no rather than sv_2mortal(newSViv(0)))

I've also pushed a branch davem/boolref2 that allows the ref() function to
be optimised in boolean context; so 'if (ref $r) {...}' doesn't have to
generate a temporary string like "Foo=ARRAY(0xc8afd8)". I intend to merge
this after 5.26, and maybe booleanise a few more ops too (like length()).

SUMMARY:
      1:30 RT #130385 Bleadperl breaks DNS-LDNS
      5:18 [perl #130198] chop(@x =~ tr///)
     22:53 [perl #78288] ref and other ops are inefficient in boolean context
      1:30 investigate making find_by_class faster()
      3:04 process p5p mailbox
    ------
     34:15 TOTAL (HH::MM)



-- 
I thought I was wrong once, but I was mistaken.
0
davem
1/11/2017 6:30:08 PM
perl.perl5.porters 46217 articles. 0 followers. Follow

2 Replies
14 Views

Similar Articles

[PageSpeed] 22


On 01/11/2017 07:30 PM, Dave Mitchell wrote:
> (this report covers two weeks)
>
> I spent the bulk of my time over the last two weeks sorting out
> infrastructure for ops which are called in boolean context.
>
> Currently PADHV and RV2HV ops are flagged specially if they are not only
> used in scalar context, but where the result they return will only
> ever be used as a boolean value; for example 'if (%h) {...}'
>
> This was originally done since a hash in scalar context returned a bucket
> usage ratio, which became expensive to calculate when we no longer
> stored the bucket occupancy count with each hash.
>
> In 5.25.x we've changed it so that in scalar context it now only returns a
> key count, which is always known and doesn't need to be calculated on the
> fly. But it can still be quicker to return just a boolean value in
> these cases rather than an integer.
>
> My work took this special-case boolean context detection code in the
> peephole optimiser, and improved it so that:
>
>  * it fixes a bunch of bugs - e.g. if (!%h) {...} wasn't recognised as
>    boolean;
>  * it expands the number of situations that are recognised as boolean
>    context, such as grep:  e.g. grep %$_, @AoH;
>  * it adds a reasonably comprehensive set of tests for checking that ops
>    have been flagged as boolean under various boolean scenarios;
>  * it allows other ops to be easily added to the boolean detection in the
>    optimiser; and to the test suite.
>
> I've also tweaked RV2HV so that in the negative case it just returns
> &PL_sv_no rather than sv_2mortal(newSViv(0)))
>
> I've also pushed a branch davem/boolref2 that allows the ref() function to
> be optimised in boolean context; so 'if (ref $r) {...}' doesn't have to
> generate a temporary string like "Foo=ARRAY(0xc8afd8)". I intend to merge
> this after 5.26, and maybe booleanise a few more ops too (like length()).


Thanks for the extensive report. This seems promising.

Do you happen to have any benchmarks for the differences this could mean
in performance?

>
> SUMMARY:
>       1:30 RT #130385 Bleadperl breaks DNS-LDNS
>       5:18 [perl #130198] chop(@x =~ tr///)
>      22:53 [perl #78288] ref and other ops are inefficient in boolean context
>       1:30 investigate making find_by_class faster()
>       3:04 process p5p mailbox
>     ------
>      34:15 TOTAL (HH::MM)

+1!
0
xsawyerx
1/12/2017 11:03:07 AM
On Thu, Jan 12, 2017 at 12:03:07PM +0100, Sawyer X wrote:
> Do you happen to have any benchmarks for the differences this could mean
> in performance?

From the commit message:

    Porting/bench.pl shows for the expression !ref($r), approximately:
        unchanged         for a non-reference $r
        doubling of speed for a reference $r
        tripling of speed for a blessed reference $r


-- 
But Pity stayed his hand. "It's a pity I've run out of bullets",
he thought. -- "Bored of the Rings"
0
davem
1/12/2017 11:23:02 AM
Reply: