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

Re: [perl #129802]

Thread Previous | Thread Next
From:
demerphq
Date:
October 30, 2016 09:30
Subject:
Re: [perl #129802]
Message ID:
CANgJU+V6UtZU-Cx1zswVgpAn_ND2Sk63qd=NbFf617VnrViDmQ@mail.gmail.com
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.

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