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 ]

tsee (4409)

tsee
  reversethis-{gro.napc} {ta} {relleums}
http://steffen-mueller.net/

You can find most of my Open Source Perl software in my CPAN directory [cpan.org].

Journal of tsee (4409)

Monday November 03, 2008
04:22 AM

Marcel's accessor generator benchmarking

[ #37791 ]

So Marcel has been benchmarking accessor generators. He used Class::Accessor::Fast::XS which is a verbatim copy of Class::XSAccessor with the Class::Accessor interfacing code added. But he missed out on the fastest ones bar XS accessor hand-rolling. It's a combination of using Object::Tiny's constructor and Class::XSAccessor's accessor generation. (Let's call it Object::Tiny::XS!) Here's the adapted code and then the results:

Benchmarking attribute access only

#!/usr/bin/env perl

use warnings;
use strict;
use Benchmark qw(cmpthese timethese :hireswallclock);

package WithMoose;
use Moose;
has myattr => ( is => 'rw' );

package WithMooseImmutable;
use Moose;
has myattr => ( is => 'rw' );
__PACKAGE__->meta->make_immutable;

package WithMouse;
use Mouse;
has myattr => ( is => 'rw' );

package WithClassAccessor;
use base qw(Class::Accessor);
__PACKAGE__->mk_accessors(qw/myattr/);

package WithClassAccessorFast;
use base qw(Class::Accessor::Fast);
__PACKAGE__->mk_accessors(qw/myattr/);

package WithClassAccessorFastXS;
use base qw(Class::Accessor::Fast::XS);
__PACKAGE__->mk_accessors(qw/myattr/);

packag e WithClassAccessorComplex;
use base qw(Class::Accessor::Complex);
__PACKAGE__->mk_new->mk_scalar_accessors(qw/myatt r/);

package WithClassAccessorConstructor;
use base qw(Class::Accessor::Constructor Class::Accessor::Complex);
__PACKAGE__->mk_constructor->mk_scalar_accessors(qw/ myattr/);

package WithMojo;
use base qw(Mojo::Base);
__PACKAGE__->attr('myattr');

package WithClassMethodMaker;
use Class::MethodMaker
    [ scalar => [ qw/myattr/ ],
      new    => [ qw/-hash new/ ],
    ];

package WithAccessors;
use accessors qw(myattr);

sub new { bless {}, shift }

package WithObjectTiny;
use Object::Tiny qw/myattr/;
sub set_myattr { $_[0]->{myattr} = $_[1] }

package WithSpiffy;
use Spiffy -base;
field 'myattr';

package WithClassSpiffy;
use Class::Spiffy -base;
field 'myattr';

package WithClassXSAccessor;
use Class::XSAccessor accessors => { myattr => 'myattr' };
sub new {my $class = shift; bless {@_} => $class}

package WithClassXSAccessorArray;
use Class::XSAccessor::Array accessors=> { myattr => 0 };
sub new {my $class = shift; my %args = @_; bless [$args{myattr}] => $class}

package WithObjectTinyXS;
use Object::Tiny qw/myattr/;
use Class::XSAccessor accessors => { myattr => 'myattr' }, replace => 1;

package main;

my $moose                      = WithMoose->new;
my $moose_immutable            = WithMooseImmutable->new;
my $mouse                      = WithMouse->new;
my $class_accessor             = WithClassAccessor->new;
my $class_accessor_fast        = WithClassAccessorFast->new;
my $class_accessor_fast_xs     = WithClassAccessorFastXS->new;
my $class_accessor_complex     = WithClassAccessorComplex->new;
my $class_accessor_constructor = WithClassAccessorConstructor->new;
my $mojo                       = WithMojo->new;
my $class_methodmaker          = WithClassMethodMaker->new;
my $accessors                  = WithAccessors->new;
my $object_tiny                = WithObjectTiny->new;
my $spiffy                     = WithSpiffy->new;
my $class_spiffy               = WithClassSpiffy->new;
my $direct_hash                = {};
my $class_xsaccessor           = WithClassXSAccessor->new;
my $class_xsaccessor_array     = WithClassXSAccessorArray->new;
my $object_tiny_xs             = WithObjectTinyXS->new;

cmpthese(timethese(-5,{
    moose => sub {
        $moose->myattr(27);
        my $x = $moose->myattr;
    },
    moose_immutable => sub {
        $moose_immutable->myattr(27);
        my $x = $moose_immutable->myattr;
    },
    mouse => sub {
        $mouse->myattr(27);
        my $x = $mouse->myattr;
    },
    class_accessor => sub {
        $class_accessor->myattr(27);
        my $x = $class_accessor->myattr;
    },
    class_accessor_fast => sub {
        $class_accessor_fast->myattr(27);
        my $x = $class_accessor_fast->myattr;
    },
    class_accessor_fast_xs => sub {
        $class_accessor_fast_xs->myattr(27);
        my $x = $class_accessor_fast_xs->myattr;
    },
    class_accessor_complex => sub {
        $class_accessor_complex->myattr(27);
        my $x = $class_accessor_complex->myattr;
    },
    class_accessor_constructor => sub {
        $class_accessor_constructor->myattr(27);
        my $x = $class_accessor_constructor->myattr;
    },
    mojo => sub {
        $mojo->myattr(27);
        my $x = $mojo->myattr;
    },
    class_methodmaker => sub {
        $class_methodmaker->myattr(27);
        my $x = $class_methodmaker->myattr;
    },
    accessors => sub {
        $accessors->myattr(27);
        my $x = $accessors->myattr;
    },
    object_tiny => sub {
        $object_tiny->set_myattr(27);
        my $x = $object_tiny->myattr;
    },
    spiffy => sub {
        $spiffy->myattr(27);
        my $x = $spiffy->myattr;
    },
    class_spiffy => sub {
        $class_spiffy->myattr(27);
        my $x = $class_spiffy->myattr;
    },
    direct_hash => sub {
        $direct_hash->{myattr} = 27;
        my $x = $direct_hash->{myattr};
    },
    object_tiny_xs => sub {
        $object_tiny_xs->myattr(27);
        my $x = $object_tiny_xs->myattr;
    },
    class_xsaccessor => sub {
        $class_xsaccessor->myattr(27);
        my $x = $class_xsaccessor->myattr;
    },
    class_xsaccessor_array => sub {
        $class_xsaccessor_array->myattr(27);
        my $x = $class_xsaccessor_array->myattr;
    },
}));

Results:

class_accessor_constructor   2454/s
moose                        4989/s
mouse                       11187/s
class_methodmaker           35946/s
mojo                        52058/s
class_accessor_complex      54325/s
moose_immutable             60575/s
class_accessor              75348/s
class_spiffy                79642/s
class_accessor_fast         89620/s
class_accessor_fast_xs     107349/s
spiffy                     134988/s
class_xsacessor_array      155608/s
class_xsacessor            173799/s
object_tiny                234721/s
object_tiny_xs             287949/s
direct_hash                449616/s

Benchmarking object creation and attribute access

#!/usr/bin/env perl

use warnings;
use strict;
use Benchmark qw(cmpthese timethese :hireswallclock);

package WithMoose;
use Moose;
has myattr => ( is => 'rw' );

package WithMooseImmutable;
use Moose;
has myattr => ( is => 'rw' );
__PACKAGE__->meta->make_immutable;

package WithMouse;
use Mouse;
has myattr => ( is => 'rw' );

package WithClassAccessor;
use base qw(Class::Accessor);
__PACKAGE__->mk_accessors(qw/myattr/);

package WithClassAccessorFast;
use base qw(Class::Accessor::Fast);
__PACKAGE__->mk_accessors(qw/myattr/);

package WithClassAccessorFastXS;
use base qw(Class::Accessor::Fast::XS);
__PACKAGE__->mk_accessors(qw/myattr/);

packag e WithClassAccessorComplex;
use base qw(Class::Accessor::Complex);
__PACKAGE__->mk_new->mk_scalar_accessors(qw/myatt r/);

package WithClassAccessorConstructor;
use base qw(Class::Accessor::Constructor Class::Accessor::Complex);
__PACKAGE__->mk_constructor->mk_scalar_accessors(qw/ myattr/);

package WithMojo;
use base qw(Mojo::Base);
__PACKAGE__->attr('myattr');

package WithClassMethodMaker;
use Class::MethodMaker
    [ scalar => [ qw/myattr/ ],
      new    => [ qw/-hash new/ ],
    ];

package WithAccessors;
use accessors qw(myattr);

sub new { bless {}, shift }

package WithObjectTiny;
use Object::Tiny qw/myattr/;
sub set_myattr { $_[0]->{myattr} = $_[1] }

package WithSpiffy;
use Spiffy -base;
field 'myattr';

package WithClassSpiffy;
use Class::Spiffy -base;
field 'myattr';

package WithClassXSAccessor;
use Class::XSAccessor accessors => { myattr => 'myattr' };
sub new {my $class = shift; bless {@_} => $class}

package WithClassXSAccessorArray;
use Class::XSAccessor::Array accessors=> { myattr => 0 };
sub new {my $class = shift; my %args = @_; bless [$args{myattr}] => $class}

package WithObjectTinyXS;
use Object::Tiny qw/myattr/;
use Class::XSAccessor accessors => { myattr => 'myattr' }, replace => 1;

package main;

cmpthese(timethese(-5,{
    moose => sub {
        my $obj = WithMoose->new(myattr => 27);
        my $x = $obj->myattr;
    },
    moose_immutable => sub {
        my $obj = WithMooseImmutable->new(myattr => 27);
        my $x = $obj->myattr;
    },
    mouse => sub {
        my $obj = WithMouse->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_accessor => sub {
        my $obj = WithClassAccessor->new({ myattr => 27 });
        my $x = $obj->myattr;
    },
    class_accessor_fast => sub {
        my $obj = WithClassAccessorFast->new({ myattr => 27 });
        my $x = $obj->myattr;
    },
    class_accessor_fast_xs => sub {
        my $obj = WithClassAccessorFastXS->new({ myattr => 27 });
        my $x = $obj->myattr;
    },
    class_accessor_complex => sub {
        my $obj = WithClassAccessorComplex->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_accessor_constructor => sub {
        my $obj = WithClassAccessorConstructor->new(myattr => 27);
        my $x = $obj->myattr;
    },
    mojo => sub {
        my $obj = WithMojo->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_methodmaker => sub {
        my $obj = WithClassMethodMaker->new(myattr => 27);
        my $x = $obj->myattr;
    },
    object_tiny => sub {
        my $obj = WithObjectTiny->new(myattr => 27);
        my $x = $obj->myattr;
    },
    spiffy => sub {
        my $obj = WithSpiffy->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_spiffy => sub {
        my $obj = WithClassSpiffy->new(myattr => 27);
        my $x = $obj->myattr;
    },
    direct_hash => sub {
        my $h = {};
        $h->{myattr} = 27;
        my $x = $h->{myattr};
    },
    object_tiny_xs => sub {
        my $obj = WithObjectTinyXS->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_xsacessor => sub {
        my $obj = WithClassXSAccessor->new(myattr => 27);
        my $x = $obj->myattr;
    },
    class_xsacessor_array => sub {
        my $obj = WithClassXSAccessorArray->new(myattr => 27);
        my $x = $obj->myattr;
    },
}));

Results:

class_accessor              159366/s
mojo                        240146/s
class_spiffy                250628/s
mouse                       270458/s
spiffy                      277170/s
moose                       288516/s
moose_immutable             293403/s
class_accessor_fast         295518/s
class_accessor_constructor  302447/s
accessors                   318795/s
class_accessor_complex      352492/s
class_methodmaker           389809/s
object_tiny                 435876/s
class_xsaccessor            537101/s
class_accessor_fast_xs      572424/s
class_xsaccessor_array      620285/s
object_tiny_xs              638328/s
direct_hash                1183721/s

I'll leave the analysis of the results to the reader.

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.