develooper Front page | perl.perl5.porters | Postings from October 2016

Re: [perl #129802]

Thread Previous | Thread Next
From:
demerphq
Date:
October 30, 2016 10:11
Subject:
Re: [perl #129802]
Message ID:
CANgJU+Wr-Jm1OV-mSUs34v7MBj8xiAgNf_NQRKWu9Ld=frJWNA@mail.gmail.com
On 30 October 2016 at 10:30, demerphq <demerphq@gmail.com> wrote:
> On 30 October 2016 at 09:57, demerphq <demerphq@gmail.com> wrote:
>> On 30 October 2016 at 09:51, demerphq <demerphq@gmail.com> wrote:
>>> On 29 October 2016 at 09:46, Leszek Dubiel
>>> <leszek.dubiel@dubielvitrum.pl> wrote:
>>>>
>>>> I have tested program below for $ARGV[0] in range of 0 to 2000 (two
>>>> twousand).
>>>>
>>>>
>>>> #!/usr/bin/perl
>>>>
>>>> use strict;
>>>> use warnings;
>>>> use Benchmark 'cmpthese';
>>>>
>>>> my $s = "A"x (2**16 + 5 - $ARGV[0]);
>>>> my $cat = 'B' . $s . 'B';
>>>> my $spr = sprintf "B%sB", $s;
>>>>
>>>> cmpthese(-1, {
>>>>          "assign" => sub { my $i=0; $s =~ /./ while $i++ < 100 },
>>>>          "concat" => sub { my $i=0; $cat =~ /./ while $i++ < 100 },
>>>>         "string" => sub { my $i=0; $spr =~ /./ while $i++ < 100 }
>>>> });
>>>> ########### end
>>>>
>>>>
>>>> During this long run:
>>>>
>>>>        -- "concat" was extremely slow in 500 (five hundred) cases, every
>>>> fourth run -- $ARGV[0] = 0, 2, 4, 8, 12, 16, ...
>>>>
>>>>       -- "assing" was extremely slow for $ARGV[0] =  6,  262,  518, 774,
>>>> 1030,  1286,  1542,  1798, ...
>>>>
>>>>          -- "string" was extremely slow for $ARGV[0] = 8,  264, 520,  776,
>>>> 1032,  1288,  1544,  1800, ...
>>>>
>>>>
>>>>
>>>> My function works on reference to big string, and here is ugly workaround --
>>>> check if program is running extremely slow, and add one space to string in
>>>> that case (15 seconds):
>>>>
>>>> sub ... {
>>>>
>>>> while () {
>>>>
>>>>     my $a = ... # big text
>>>>
>>>>         # matching big text ...
>>>>     use v5.10;
>>>>     state $t = time;
>>>>     if (time > $t + 15) {
>>>>         my $x = pos $$a;
>>>>         $a .= " ";
>>>>         pos $a = $x;
>>>>         $t = time;
>>>>     }
>>>>  }
>>>> }
>>>
>>> You have not told us your OS, or the version of Perl you are using,
>>> and I cannot replicate this issue, so it is hard to say much.
>>>
>>> Can you please provide the output of perl -V, and details about your os, etc.
>>
>> Actually, playing more, I can replicate in blead on linux (low numbers
>> are I think due to DEBUGGING build)
>>
>> $ ./perl -Ilib t.pl 0
>>           Rate concat string assign
>> concat  3110/s     --   -86%   -86%
>> string 21920/s   605%     --    -0%
>> assign 21976/s   607%     0%     --
>>
>> However perl 5.18.4 does not have this issue.
>>
>> $ perl t.pl 0
>>           Rate assign concat string
>> assign 62877/s     --    -0%    -1%
>> concat 63015/s     0%     --    -1%
>> string 63434/s     1%     1%     --
>>
>> My first guess is that this is an issue with COW and/or malloc.
>
> Well, it is COW, but indirectly.
>
> Modifying your test code to show more detail:
>
> $ cat t.pl
> #!/usr/bin/perl
>
> use strict;
> use warnings;
> use Benchmark 'cmpthese';
> print "Perl version $]\n";
> use Devel::Peek;
>
> my $mod = $ARGV[0] || 0;
>
> my $assign = "A"x (2**16 + 5 - $mod);
> my $concat = 'B' . $assign . 'B';
> my $string = sprintf "B%sB", $assign;
>
> print STDERR "assign\n";
> Dump($assign);
> print STDERR "concat\n";
> Dump($concat);
> print STDERR "string\n";
> Dump($string);
>
> cmpthese(-1, {
>         "assign" => sub { my $i=0; $assign =~ /./ while $i++ < 100 },
>         "concat" => sub { my $i=0; $concat =~ /./ while $i++ < 100 },
>         "string" => sub { my $i=0; $string =~ /./ while $i++ < 100 }
> });
>
> and then running it like this:
>
> ./perl -Ilib t.pl 0 2>&1 | perl -pe's/A+/A+/g;'
>
> We get this:
>
> $ ./perl -Ilib t.pl 0 2>&1 | perl -pe's/A+/A+/g;'
> assign
> SV = PV(0xfa8c38) at 0x10575d8
>   REFCNT = 1
>   FLA+GS = (POK,pPOK)
>   PV = 0x1195e88 "A+"\0
>   CUR = 65541
>   LEN = 65544
> concat
> SV = PV(0xfa8c58) at 0x1171848
>   REFCNT = 1
>   FLA+GS = (POK,pPOK)
>   PV = 0x11a5eb8 "BA+B"\0
>   CUR = 65543
>   LEN = 65544
> string
> SV = PV(0xfa8c88) at 0x1114bd0
>   REFCNT = 1
>   FLA+GS = (POK,pPOK)
>   PV = 0x11b5ee8 "BA+B"\0
>   CUR = 65543
>   LEN = 65552
> Perl version 5.025007
>           Rate concat string assign
> concat  3257/s     --   -84%   -85%
> string 20597/s   532%     --    -6%
> assign 21920/s   573%     6%     --
>
> From which we can see that:
>
> concat
>    CUR = 65543
>   LEN = 65544
>
> Which does not leave enough room for the refcount. So a point fix
> would appear to be to make sure that concat properly overallocates.

Also, we need to remove the exemption for powers-of-2 rule, as it
causes perf degradation too.

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