% perl-5.8.2 /tmp/append
Rate append concat
append 33333/s -- -7%
concat 35714/s 7% --
% perl-5.8.3 /tmp/append
Rate concat append
concat 5141/s -- -87%
append 38462/s 648% --
The benchmark:
use Benchmark qw(cmpthese) ;
my $chunk = "x" x 4096;
cmpthese(20000, {
append => \&append,
concat => \&concat,
});
sub append {
my $buffer = '';
for (1..10) {
$buffer .= $chunk;
}
}
sub concat {
my $buffer = '';
for (1..10) {
$buffer = $buffer . $chunk;
}
}
The two have been built in exactly the same way, diffing perl -V shows the
only difference in a minor subversion of gcc:
- ccversion='', gccversion='3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk)',
gccosandvers=''
+ ccversion='', gccversion='3.3.1 (Mandrake Linux 9.2 3.3.1-4mdk)',
gccosandvers=''
I guess I could try rebuilding 5.8.2 with the same gcc, but I'm not sure if
that's the cause of the difference, since appending performes identically
under both.
FWIW, perlbench scores an identical average, though some values quite diverge.
Though the bench probably doesn't include the concat test.
A) perl-5.008002
path = /usr//bin/perl-5.8.3
cc = cc
optimize = -g
ccflags = -DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm
usemymalloc = n
B) perl-5.008002
path = /usr//bin/perl-5.8.2
cc = cc
optimize = -g
ccflags = -DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm
usemymalloc = n
A B
---- ----
arith/mixed 100 89
arith/trig 100 101
array/copy 100 73
array/foreach 100 100
array/index 100 102
array/pop 100 99
array/shift 100 104
array/sort-num 100 99
array/sort 100 102
call/0arg 100 101
call/1arg 100 91
call/2arg 100 98
call/9arg 100 101
call/empty 100 99
call/fib 100 103
call/method 100 98
call/wantarray 100 104
hash/copy 100 100
hash/each 100 105
hash/foreach-sort 100 101
hash/foreach 100 99
hash/get 100 92
hash/set 100 99
loop/for-c 100 104
loop/for-range-const 100 103
loop/for-range 100 99
loop/getline 100 101
loop/while-my 100 102
loop/while 100 99
re/const 100 101
re/w 100 104
startup/fewmod 100 109
startup/lotsofsub 100 81
startup/noprog 100 113
string/base64 100 99
string/htmlparser 100 94
string/index-const 100 96
string/index-var 100 101
string/ipol 100 131
string/tr 100 102
AVERAGE 100 100
Here is the full config of both builds
perl-5.8.2 -V
Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
Platform:
osname=linux, osvers=2.4.22-10mdk, archname=i686-linux
uname='linux rabbit.stason.org 2.4.22-10mdk #1 thu sep 18 12:30:58 cest
2003 i686 unknown unknown gnulinux '
config_args='-des -Dprefix=/home/stas/perl/5.8.2 -Doptimize=-g
-Duseshrplib -Dusedevel'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-g',
cppflags='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-I/usr/include/gdbm'
ccversion='', gccversion='3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk)',
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version='2.3.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic
-Wl,-rpath,/home/stas/perl/5.8.2/lib/5.8.2/i686-linux/CORE'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: DEBUGGING USE_LARGE_FILES
Built under linux
Compiled at Nov 5 2003 16:45:08
%ENV:
PERLDOC_PAGER="less -R"
@INC:
/home/stas/perl/5.8.2/lib/5.8.2/i686-linux
/home/stas/perl/5.8.2/lib/5.8.2
/home/stas/perl/5.8.2/lib/site_perl/5.8.2/i686-linux
/home/stas/perl/5.8.2/lib/site_perl/5.8.2
/home/stas/perl/5.8.2/lib/site_perl
.
perl-5.8.3 -V
Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
Platform:
osname=linux, osvers=2.4.22-10mdk, archname=i686-linux
uname='linux rabbit.stason.org 2.4.22-10mdk #1 thu sep 18 12:30:58 cest
2003 i686 unknown unknown gnulinux '
config_args='-des -Dprefix=/home/stas/perl/5.8.3 -Doptimize=-g
-Duseshrplib -Dusedevel'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-g',
cppflags='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include
-I/usr/include/gdbm'
ccversion='', gccversion='3.3.1 (Mandrake Linux 9.2 3.3.1-4mdk)',
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version='2.3.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic
-Wl,-rpath,/home/stas/perl/5.8.3/lib/5.8.2/i686-linux/CORE'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: DEBUGGING USE_LARGE_FILES
Locally applied patches:
MAINT21829
Built under linux
Compiled at Dec 1 2003 11:47:41
%ENV:
PERLDOC_PAGER="less -R"
@INC:
/home/stas/perl/5.8.3/lib/5.8.2/i686-linux
/home/stas/perl/5.8.3/lib/5.8.2
/home/stas/perl/5.8.3/lib/site_perl/5.8.2/i686-linux
/home/stas/perl/5.8.3/lib/site_perl/5.8.2
/home/stas/perl/5.8.3/lib/site_perl
.
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:st...@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
I blame this change :
Change 21752 by rgs@rgs-home on 2003/11/19 21:06:01
Fix bug [perl #24508] Wrong assignment in nested assignment
together with subroutine call
Apparently concat still doesn't deal correctly with lexicals
in all cases. Disable the whole TARGET_MY optimisation for it.
(and remove the corresponding code from the peephole optimiser.)
Affected files ...
... //depot/perl/op.c#592 edit
... //depot/perl/opcode.h#89 edit
... //depot/perl/opcode.pl#107 edit
... //depot/perl/t/op/concat.t#7 edit
Yay, thanks Rafael... As someone who wrote many benchmarks comparing various
methods to join bits and pieces together in perl, it's interesting how
switching perl versions may turn any conclusions wrong ;)
> Affected files ...
>
> ... //depot/perl/op.c#592 edit
> ... //depot/perl/opcode.h#89 edit
> ... //depot/perl/opcode.pl#107 edit
> ... //depot/perl/t/op/concat.t#7 edit
--
The optimization that I removed what trigerred only for code like
$lexical = $term1.$term2
ie. not for assignment to package variables, and not for chained
concatenations.
With more tuits, it's worthwhile trying to reintegrate a similar
optimization, but one that produces correct results :)
please try again with blead@21951.
Objections welcome.
Regards,
Adi
Looks great to me:
perl-blead-ithread@21951 /tmp/append
Rate concat append
concat 25316/s -- -11%
append 28571/s 13% --
I guess it's not in maint:
perl-5.8.3-ithread@21949 /tmp/append
Rate concat append
concat 3650/s -- -86%
append 26667/s 631% --
and not in perl-5.8.3@22000, any reason why this patch wasn't backported to
maint? Nick, please notice that this slowdown is not in 5.8.2. So I think it's
worth restoring it for 5.8.3.
> and not in perl-5.8.3@22000, any reason why this patch wasn't backported to
> maint? Nick, please notice that this slowdown is not in 5.8.2. So I think
> it's worth restoring it for 5.8.3.
Please notice that there was a bug in 5.8.2
I don't understand it enough to know whether it creates new bugs.
No-one else has commented on it.
Nicholas Clark
The diff <21752 vs. >21951 is exactly this:
Perl_ck_concat(pTHX_ OP *o)
{
OP *kid = cUNOPo->op_first;
- if (kid->op_type == OP_CONCAT && !(kUNOP->op_first->op_flags & OPf_MOD))
+ if (kid->op_type == OP_CONCAT && !(kid->op_private & OPpTARGET_MY) &&
+ !(kUNOP->op_first->op_flags & OPf_MOD))
o->op_flags |= OPf_STACKED;
return o;
}
So my patch simply avoids the stacked concat optimization in the case
where the OP target is a lexical. It's _NOT_ a new optimization.
The other more general OPpTARGET_MY ck_sassign() optimization (which
21752 dropped for concat) was/is a very valuable one: it gets rid of at
least two active OPs, a SvSetSV and an extra temporary SV in the pad.
It's there since long time and applies to almost all cases where the
lvalue is a lexical.
Frankly, I don't see the point of always suggesting that my little
obvious patches "should" introduce new bugs.
This becomes tedious - and I'm going to reconsider the perspective
of having to stand it in the future.
A happy new year,
Adi
Funny you should post this, I was looking at the exact same diff just now.
> The other more general OPpTARGET_MY ck_sassign() optimization (which
> 21752 dropped for concat) was/is a very valuable one: it gets rid of at
> least two active OPs, a SvSetSV and an extra temporary SV in the pad.
> It's there since long time and applies to almost all cases where the
> lvalue is a lexical.
I can see it now. And thanks for the patch.
> Frankly, I don't see the point of always suggesting that my little
> obvious patches "should" introduce new bugs.
> This becomes tedious - and I'm going to reconsider the perspective
> of having to stand it in the future.
Please don't; blame it on our incompetence / lack of free time / laziness.
May I just suggest that you cc: some of your patches to P5P with some
explanation -- sometimes the log comment isn't enough to figure it out
-- and moreover (and selfishly) this will help the poor summarizer guy,
whose copious free time is sometimes lacking.
Thanks for the explanation. It's about to be in (running tests)
> Frankly, I don't see the point of always suggesting that my little
> obvious patches "should" introduce new bugs.
> This becomes tedious - and I'm going to reconsider the perspective
> of having to stand it in the future.
Sorry to sound like a niggly bugger, but this is stuff I don't understand.
It's not obvious to me, and I think to most of p5p. We can benefit from
your expertise in these areas, but if no-one else comments, then I'm going
to have to ask "what does this do?" for the cases where I don't understand.
In this case I understand neither the cause of the bug, nor what the peephole
optimiser is up to in the general case.
Similarly the PL_sv_placeholder in perl_destruct - I wasn't aware of the
difference between that and sv_undef. After chasing through some of the code
that now makes sense.
You are welcome to contribute as little or as much as you wish. I'm
grateful for everything that you (and everyone else) contributes - if
no-one volunteered their time and expertise we not be where we are today.
Nicholas Clark