Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jk2addict (4946)

jk2addict
  (email not shown publicly)
http://today.icantfocus.com/blog/
AOL IM: chrislaco (Add Buddy, Send Message)
Yahoo! ID: chrislaco@sbcglobal.net (Add User, Send Message)
Jabber: laco@scribblewerks.com

Journal of jk2addict (4946)

Saturday December 22, 2007
07:23 PM

5.10: Why is this slower?

[ #35189 ]

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • 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.
    • BTW, debug this by comparing the output of B::Concise on 5.8.whatever vs 5.10.0.
  • 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.
    • 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,

      • 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 :-)
        • 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 :-)