Skip to content

Instantly share code, notes, and snippets.

@sapphirecat
Forked from schwern/gist:896004
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sapphirecat/0a0a75aff048b6335ac1 to your computer and use it in GitHub Desktop.
Save sapphirecat/0a0a75aff048b6335ac1 to your computer and use it in GitHub Desktop.
Perl object access showdown, incl. Class::XSAccessor
#!/usr/bin/env perl
use strict;
use warnings;
use Carp;
BEGIN {
# uncomment to test pure Perl Mouse
# $ENV{MOUSE_PUREPERL} = 1;
}
# ...........hash...............
my $hash = {};
sub hash_nc {
$hash->{bar} = 32;
my $x = $hash->{bar};
}
# ...........hash with check...............
my $hash_check = {};
sub hash {
my $arg = 32;
croak "we take an integer" unless defined $arg and $arg =~ /^[+-]?\d+$/;
$hash_check->{bar} = $arg;
my $x = $hash_check->{bar};
}
# ...........by hand..............
{
package Foo::Manual::NoChecks;
sub new { bless {} => shift }
sub bar {
my $self = shift;
return $self->{bar} unless @_;
$self->{bar} = shift;
}
}
my $manual_nc = Foo::Manual::NoChecks->new;
sub manual_nc {
$manual_nc->bar(32);
my $x = $manual_nc->bar;
}
# ...........by hand with checks..............
{
package Foo::Manual;
use Carp;
sub new { bless {} => shift }
sub bar {
my $self = shift;
if( @_ ) {
# Simulate argument checking
my $arg = shift;
croak "we take an integer" unless defined $arg and $arg =~ /^[+-]?\d+$/;
$self->{bar} = $arg;
}
return $self->{bar};
}
}
my $manual = Foo::Manual->new;
sub manual {
$manual->bar(32);
my $x = $manual->bar;
}
#.............Mouse.............
{
package Foo::Mouse;
use Mouse;
has bar => (is => 'rw', isa => "Int");
__PACKAGE__->meta->make_immutable;
}
my $mouse = Foo::Mouse->new;
sub mouse {
$mouse->bar(32);
my $x = $mouse->bar;
}
#............Moose............
{
package Foo::Moose;
use Moose;
has bar => (is => 'rw', isa => "Int");
__PACKAGE__->meta->make_immutable;
}
my $moose = Foo::Moose->new;
sub moose {
$moose->bar(32);
my $x = $moose->bar;
}
#.............Moo...........
{
package Foo::Moo;
use Moo;
has bar => (is => 'rw', isa => sub { $_[0] =~ /^[+-]?\d+$/ });
}
my $moo = Foo::Moo->new;
sub moo {
$moo->bar(32);
my $x = $moo->bar;
}
#........... Moo using Sub::Quote..............
{
package Foo::Moo::QS;
use Moo;
use Sub::Quote;
has bar => (is => 'rw', isa => quote_sub q{ $_[0] =~ /^[+-]?\d+$/ });
}
my $mooqs = Foo::Moo::QS->new;
sub mooqs {
$mooqs->bar(32);
my $x = $mooqs->bar;
}
#............Object::Tiny..............
{
package Foo::Object::Tiny;
use Object::Tiny qw(bar);
}
my $ot = Foo::Object::Tiny->new( bar => 32 );
sub ot {
my $x = $ot->bar;
}
#............Object::Tiny::XS..............
{
package Foo::Object::Tiny::XS;
use Object::Tiny::XS qw(bar);
}
my $otxs = Foo::Object::Tiny::XS->new(bar => 32);
sub otxs {
my $x = $otxs->bar;
}
#............Class::XSAccessor..............
{
package Foo::Class::XSAccessor;
use Class::XSAccessor {
constructor => 'new',
accessors => [qw(bar)],
};
}
my $cxsa = Foo::Class::XSAccessor->new(bar => 32);
sub cxsa {
my $x = $cxsa->bar;
}
use Benchmark 'timethese';
print "Testing Perl $], Moose $Moose::VERSION, Mouse $Mouse::VERSION, Moo $Moo::VERSION\n";
timethese(
6_000_000,
{
# Moose => \&moose,
Mouse => \&mouse,
manual => \&manual,
"manual, no check" => \&manual_nc,
'hash, no check' => \&hash_nc,
hash => \&hash,
# Moo => \&moo,
# "Moo w/quote_sub" => \&mooqs,
"Object::Tiny" => \&ot,
"Object::Tiny::XS" => \&otxs,
"Class::XSAcc" => \&cxsa,
}
);
__END__
Testing Perl 5.012002, Moose 1.24, Mouse 0.91, Moo 0.009007, Object::Tiny 1.08, Object::Tiny::XS 1.01
Benchmark: timing 6000000 iterations of Moo, Moo w/quote_sub, Moose, Mouse, Object::Tiny, Object::Tiny::XS, hash, manual, manual with no checks...
Object::Tiny::XS: 1 secs ( 1.20 usr + -0.01 sys = 1.19 CPU) @ 5042016.81/s
hash, no check : 3 secs ( 1.86 usr + 0.01 sys = 1.87 CPU) @ 3208556.15/s
Mouse : 3 secs ( 3.66 usr + 0.00 sys = 3.66 CPU) @ 1639344.26/s
Object::Tiny : 3 secs ( 3.80 usr + 0.00 sys = 3.80 CPU) @ 1578947.37/s
hash : 5 secs ( 5.53 usr + 0.01 sys = 5.54 CPU) @ 1083032.49/s
manual, no check: 9 secs ( 9.11 usr + 0.02 sys = 9.13 CPU) @ 657174.15/s
Moo : 17 secs (17.37 usr + 0.03 sys = 17.40 CPU) @ 344827.59/s
manual : 17 secs (17.89 usr + 0.02 sys = 17.91 CPU) @ 335008.38/s
Mouse no XS : 20 secs (20.50 usr + 0.03 sys = 20.53 CPU) @ 292255.24/s
Moose : 21 secs (21.33 usr + 0.03 sys = 21.36 CPU) @ 280898.88/s
Moo w/quote_sub : 23 secs (23.07 usr + 0.04 sys = 23.11 CPU) @ 259627.87/s
# CentOS 6 guest using plenv + cpanm -L, on late 2012 iMac host
Testing Perl 5.018002, Moose 2.1205, Mouse 2.2.0, Moo 1.004002
Benchmark: timing 20000000 iterations of Moo, Moo w/quote_sub, Moose, Mouse, Object::Tiny, Object::Tiny::XS, hash, hash, no check, manual, manual, no check...
Class::XSAcc : 2 wallclock secs ( 2.56 usr + 0.00 sys = 2.56 CPU) @ 7812500.00/s (n=20000000)
Object::Tiny::XS: 3 wallclock secs ( 2.69 usr + 0.00 sys = 2.69 CPU) @ 7434944.24/s (n=20000000)
hash, no check : 4 wallclock secs ( 3.76 usr + 0.00 sys = 3.76 CPU) @ 5319148.94/s (n=20000000)
Mouse (XS) : 4 wallclock secs ( 5.59 usr + 0.01 sys = 5.60 CPU) @ 3571428.57/s (n=20000000)
Object::Tiny : 6 wallclock secs ( 6.02 usr + 0.00 sys = 6.02 CPU) @ 3322259.14/s (n=20000000)
hash : 11 wallclock secs (10.96 usr + 0.00 sys = 10.96 CPU) @ 1824817.52/s (n=20000000)
manual, no check: 13 wallclock secs (12.88 usr + 0.00 sys = 12.88 CPU) @ 1552795.03/s (n=20000000)
manual : 30 wallclock secs (29.26 usr + 0.00 sys = 29.26 CPU) @ 683527.00/s (n=20000000)
Mouse (PP) : 31 wallclock secs (32.27 usr + 0.00 sys = 32.27 CPU) @ 619770.68/s (n=20000000)
Moose : 34 wallclock secs (33.98 usr + 0.00 sys = 33.98 CPU) @ 588581.52/s (n=20000000)
Moo w/quote_sub : 71 wallclock secs (71.54 usr + 0.00 sys = 71.54 CPU) @ 279563.88/s (n=20000000)
Moo : 76 wallclock secs (75.72 usr + 0.00 sys = 75.72 CPU) @ 264131.01/s (n=20000000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment