5.10: Why is this slower?

jk2addict on 2007-12-23T00:23:16

This started off as a user reporting that Class::Accessor::Grouped was way slower on 5.10 than on 5.8.8. At this point, I call 'not it'...but only because I really don't know what in the hell is going on.

Two brand new fresh FreeBSD 6.2 installs. One with a a compiled (not ports) Perl 5.8.8 and the other with a compiled 5.10.0.

The test case is simple set_inherited, sans C::A::G in the picture, since the reporter noted set was slower as well (which BTW has no MRO interaction):

test.pl > use lib '.'; > use Foo; > use Benchmark ':all'; > > my $f = bless {}, 'Foo'; > > timethese(0, { > set_inherited_class => sub {Foo->set_inherited('bar', 'baz')}, > set_inherited_object => sub {$f->set_inherited('bar', 'baz')} > });

Foo.pm > package Foo; > use Scalar::Util qw/blessed reftype/; > > sub set_inherited { > my ($self, $set, $val) = @_; > > if (blessed $self) { > if (reftype $self eq 'HASH') { > return $self->{$set} = $val; > } else { > croak('Cannot set inherited value on an object instance that is not hash-based'); > }; > } else { > no strict 'refs'; > > return ${$self.'::__cag_'.$set} = $val; > }; > } > > 1;

The results are:

Perl 5.8.8 Machine: > Benchmark: running set_inherited_class, set_inherited_object for at least 3 CPU seconds... > set_inherited_class: 4 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 575596.40/s (n=1821223) > set_inherited_object: 3 wallclock secs ( 3.16 usr + -0.01 sys = 3.15 CPU) @ 687794.82/s (n=2165479) > claco@fbsd588 ~ $



Perl 5.10.0 Machine: > Benchmark: running set_inherited_class, set_inherited_object for at least 3 CPU seconds... > set_inherited_class: 3 wallclock secs ( 3.12 usr + 0.01 sys = 3.13 CPU) @ 335388.09/s (n=1050708) > set_inherited_object: 2 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 412676.76/s (n=1299287) > claco@fbsd510 ~ $

My to my shock, if I whittle down the code in set_inherited to just this:

> package Foo; > use Scalar::Util qw/blessed reftype/; > > sub set_inherited { > my ($self, $set, $val) = @_; > > } > > 1;

performance still seriouesly sucks:

5.8.8 > Benchmark: running set_inherited_class, set_inherited_object for at least 3 CPU seconds... > set_inherited_class: 3 wallclock secs ( 3.08 usr + 0.02 sys = 3.09 CPU) @ 1199923.07/s (n=3712262) > set_inherited_object: 4 wallclock secs ( 3.27 usr + 0.00 sys = 3.27 CPU) @ 1380589.06/s (n=4519272) > claco@fbsd588 ~ $

5.10.0 > Benchmark: running set_inherited_class, set_inherited_object for at least 3 CPU seconds... > set_inherited_class: 4 wallclock secs ( 3.09 usr + 0.01 sys = 3.10 CPU) @ 536733.34/s (n=1664712) > set_inherited_object: 4 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU) @ 638055.42/s (n=1998908) > claco@fbsd510 ~ $

A this point, I'm stumped. Just my ($, $, $) = @_ is slow. Changing that to:

my $self = shift; my $set = shift; my $val = shift

make 5.10 even facter than 5.8.8 again. I know shift is always faster...but why is 5.10 way slower than 5.8.8 when assigning @_?

My brain hurts.


It's a bug

jjore on 2007-12-23T06:48:30

The aassign opcode has the COMMON flag which indicates that perl thought you used the same variable in the right and left sides. Doing so requires perl to do additional work to make that safe. This flag should not be turned on for this case.

To perl 5.10.0, this will represent a runtime cost making it slower til the bug is fixed.

Re:It's a bug

jjore on 2007-12-23T06:52:51

BTW, debug this by comparing the output of B::Concise on 5.8.whatever vs 5.10.0.

sysmalloc vs. mymalloc

srezic on 2007-12-23T10:11:24

First, you should check if both perls were built with the same malloc setting, i.e. check if usemymalloc is the same. FreeBSD's perl from ports has usemymalloc=y, while the FreeBSD's hints file in the perl5.10.0 sources has usemymalloc=n. There are some situations where FreeBSD's malloc is much worse than perl's one.

Re:sysmalloc vs. mymalloc

jk2addict on 2007-12-23T17:13:01

I didn't install 5.8.8 from ports, so both are compiled with the defauls from Configure. Both use perls malloc. As such, it;s apples to apples. Perl got slower.

I need to test with FreeBSD malloc. If that fixes it, I vote that the Configure defaults need to change in Configure for FreeBSD. In the end, Joe User shouldn't have to go flag diving to find out why certain things are 50% slower.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=freebsd, osvers=6.2-release, archname=i386-freebsd
    uname='freebsd fbsd588.local 6.2-release freebsd 6.2-release #0: fri jan 12 10:40:27 utc 2007 root@dessler.cse.buffalo.edu:usrobjusrsrcsysgeneric i386 '
    config_args='-de'
    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 ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include',
    optimize='-O',
    cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include'
    ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', 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 ='-Wl,-E  -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lm -lcrypt -lutil -lc
    perllibs=-lm -lcrypt -lutil -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib'

Characteristics of this binary (from libperl):
  Compile-time options: PERL_MALLOC_WRAP USE_LARGE_FILES USE_PERLIO
  Built under freebsd
  Compiled at Dec 22 2007 15:52:43
  @INC:
    /usr/local/lib/perl5/5.8.8/i386-freebsd
    /usr/local/lib/perl5/5.8.8
    /usr/local/lib/perl5/site_perl/5.8.8/i386-freebsd
    /usr/local/lib/perl5/site_perl/5.8.8
    /usr/local/lib/perl5/site_perl
    .

-------------

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=freebsd, osvers=6.2-release, archname=i386-freebsd
    uname='freebsd fbsd510.local 6.2-release freebsd 6.2-release #0: fri jan 12 10:40:27 utc 2007 root@dessler.cse.buffalo.edu:usrobjusrsrcsysgeneric i386 '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    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 ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include',
    optimize='-O',
    cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', 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 ='-Wl,-E  -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lm -lcrypt -lutil -lc
    perllibs=-lm -lcrypt -lutil -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib'

Characteristics of this binary (from libperl):
  Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP
                        USE_LARGE_FILES USE_PERLIO
  Built under freebsd
  Compiled at Dec 22 2007 17:32:47
  @INC:
    /usr/local/lib/perl5/5.10.0/i386-freebsd
    /usr/local/lib/perl5/5.10.0
    /usr/local/lib/perl5/site_perl/5.10.0/i386-freebsd
    /usr/local/lib/perl5/site_perl/5.10.0
    .

Ther's a thread on PM as well. http://perlmonks.com/?node_id=658723

Re:sysmalloc vs. mymalloc

srezic on 2007-12-23T17:29:08

usemymalloc=n means that you're using FreeBSD's malloc, not perl's.
Ther's a thread on PM as well.
I know. Guess to whom you're talking to there :-)

Re:sysmalloc vs. mymalloc

jk2addict on 2007-12-23T17:33:39

Yes, I had that backwords. In either case, at least their both using the same setting. :-)

I haven't ad to hand compile a perl in ages, let alone actually look at the options :-)