http://qs321.pair.com?node_id=939011

Esteemed Monks,

I like the declarative syntax of Moose. I don't like the 728% performance hit I get compared to using a simple blessed hashref. Even Mo, minimal as it is, offers only a 27% increase in speed compared to Moose.

Benchmark Results
Benchmark: timing 1000000 iterations of blessed_hashref, hashref, mo, moose...
blessed_hashref:  1.80017 wallclock secs ( 1.79 usr +  0.00 sys =  1.79 CPU) @ 558659.22/s (n=1000000)
        hashref:  1.37839 wallclock secs ( 1.38 usr +  0.00 sys =  1.38 CPU) @ 724637.68/s (n=1000000)
             mo: 11.6823  wallclock secs (11.67 usr +  0.00 sys = 11.67 CPU) @  85689.80/s (n=1000000)
          moose: 14.8408  wallclock secs (14.82 usr +  0.00 sys = 14.82 CPU) @  67476.38/s (n=1000000)

                    Rate        moose            mo blessed_hashref      hashref
moose            67476/s           --          -21%            -88%         -91%
mo               85690/s          27%            --            -85%         -88%
blessed_hashref 558659/s         728%          552%              --         -23%
hashref         724638/s         974%          746%             30%           --
Benchmark Script:
#!/usr/bin/perl -w package MooseState; use Moose; has 'name' => ( is => 'ro', isa => 'Str', required => 1, ); has 'capital' => ( is => 'ro', isa => 'Str', required => 1, ); has 'population' => ( is => 'rw', isa => 'Int', required => 1, ); __PACKAGE__->meta->make_immutable(); package MoState; use Mo qw(required); has 'name' => ( is => 'ro', isa => 'Str', required => 1, ); has 'capital' => ( is => 'ro', isa => 'Str', required => 1, ); has 'population' => ( is => 'rw', isa => 'Int', required => 1, ); package main; use strict; use warnings 'all'; use Benchmark qw( :all :hireswallclock ); my %args = ( name => 'Colorado', capital => 'Denver', population => 5_000_000, ); my $results = timethese(1_000_000, { blessed_hashref => \&blessed_hashref, hashref => \&hashref, moose => \&moose, mo => \&mo, }); cmpthese($results); sub blessed_hashref { my $state = bless { %args }, 'Foo'; }# end blessed_hashref() sub hashref { my $state = { %args }; }# end hashref() sub moose { my $state = MooseState->new( %args ); }# end moose() sub mo { my $state = MoState->new( %args ); }# end mo()

Is there something that can be done to make constructing Moose/Mo objects much, much faster?

Update

I see now that this is a stacked comparison in that my benchmark script is having Moose do more work than it should (checking isa and required fields). As Your Mother pointed out, Mouse::XS may just be the ticket, as it's Moosey and still very fast.

Replies are listed 'Best First'.
Re: The speed of blessed hashrefs, the power of Moose - how to get both?
by Your Mother (Archbishop) on Nov 20, 2011 at 02:55 UTC
    Testing Perl 5.012002, Moose 1.24, Mouse 0.91, Moo 0.009007, Object::T +iny 1.08, Object::Tiny::XS 1.01 Benchmark: timing 6000000 iterations of Moo, Moo w/quote_sub, Moose, M +ouse, Object::Tiny, Object::Tiny::XS, hash, manual, manual with no ch +ecks... Object::Tiny::XS: 1 secs ( 1.20 usr + -0.01 sys = 1.19 CPU) @ 504201 +6.81/s hash, no check : 3 secs ( 1.86 usr + 0.01 sys = 1.87 CPU) @ 320855 +6.15/s Mouse : 3 secs ( 3.66 usr + 0.00 sys = 3.66 CPU) @ 163934 +4.26/s Object::Tiny : 3 secs ( 3.80 usr + 0.00 sys = 3.80 CPU) @ 157894 +7.37/s hash : 5 secs ( 5.53 usr + 0.01 sys = 5.54 CPU) @ 108303 +2.49/s manual, no check: 9 secs ( 9.11 usr + 0.02 sys = 9.13 CPU) @ 65717 +4.15/s Moo : 17 secs (17.37 usr + 0.03 sys = 17.40 CPU) @ 34482 +7.59/s manual : 17 secs (17.89 usr + 0.02 sys = 17.91 CPU) @ 33500 +8.38/s Mouse no XS : 20 secs (20.50 usr + 0.03 sys = 20.53 CPU) @ 29225 +5.24/s Moose : 21 secs (21.33 usr + 0.03 sys = 21.36 CPU) @ 28089 +8.88/s Moo w/quote_sub : 23 secs (23.07 usr + 0.04 sys = 23.11 CPU) @ 25962 +7.87/s

    Mouse(::XS) is probably what you want: Source. Depending on how deep you want to go with Roles and Traits it’s nearly identical code-wise. This is your benchmark with a Mouse addition–

    Rate moose mo mouse blessed_hashref + hashref moose 55157/s -- -22% -67% -86% + -88% mo 71023/s 29% -- -58% -82% + -85% mouse 168919/s 206% 138% -- -56% + -65% blessed_hashref 384615/s 597% 442% 128% -- + -20% hashref 478469/s 767% 574% 183% 24% + --
Re: The speed of blessed hashrefs, the power of Moose - how to get both?
by zwon (Abbot) on Nov 20, 2011 at 03:28 UTC
    sub blessed_hashref { my $state = bless { %args }, 'Foo'; }

    You are not checking arguments here. In definition of MooseState you specified things like isa => 'Int', so constructor checks arguments. You're testing constructions which are not functionally equal. Remove these isa or add checks to blessed_hashref to get something that makes sense.

      This is a very important point, it's a stacked comparison. You can either put in checks in the hashref (though it might provoke argument over what exactly would be equivalent), or you can take out the checks from Moose.
        If you're going to take the checks out, why use Moose? Seriously, just use a href directly. (When do you really need method calls to attributes? Encapsulation? Hello, mantra. You're adding these unnecessary layers when you don't really need it. If you need it later, add it later! Perl is not compiled. Why are you creating a static API?)
Re: The speed of blessed hashrefs, the power of Moose - how to get both?
by thargas (Deacon) on Oct 24, 2012 at 14:06 UTC
    Don't forget Moo
A reply falls below the community's threshold of quality. You may see it by logging in.