Skip to content

Instantly share code, notes, and snippets.

@markstos
Forked from schwern/gist:896004
Created August 23, 2012 03:23
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markstos/3431863 to your computer and use it in GitHub Desktop.
Save markstos/3431863 to your computer and use it in GitHub Desktop.
Benchmarking simple accessors, Moose vs Moos vs Mouse vs Moo vs hand written vs a hash
#!/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;
}
use Benchmark 'timethese';
print "Testing Perl $], Moose $Moose::VERSION, Mouse $Mouse::VERSION, Moo $Moo::VERSION\n";
timethese(
2_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,
}
);
__END__
$ perl tmp.pl
Testing Perl 5.014002, Moose 2.0603, Mouse 1.02, Moo 1.000003
Benchmark: timing 2000000 iterations of Moo, Moo w/quote_sub, Moos, Moose, Mouse, hash, hash, no check, manual, manual, no check...
Moo: 26 wallclock secs (24.51 usr + 0.00 sys = 24.51 CPU) @ 81599.35/s (n=2000000)
Moo w/quote_sub: 27 wallclock secs (25.73 usr + 0.00 sys = 25.73 CPU) @ 77730.28/s (n=2000000)
Moos: 25 wallclock secs (24.22 usr + 0.00 sys = 24.22 CPU) @ 82576.38/s (n=2000000)
Moose: 7 wallclock secs ( 7.90 usr + 0.00 sys = 7.90 CPU) @ 253164.56/s (n=2000000)
Mouse: 1 wallclock secs ( 1.08 usr + 0.00 sys = 1.08 CPU) @ 1851851.85/s (n=2000000)
hash: 3 wallclock secs ( 2.15 usr + 0.00 sys = 2.15 CPU) @ 930232.56/s (n=2000000)
hash, no check: 0 wallclock secs ( 0.65 usr + 0.00 sys = 0.65 CPU) @ 3076923.08/s (n=2000000)
manual: 7 wallclock secs ( 7.48 usr + 0.00 sys = 7.48 CPU) @ 267379.68/s (n=2000000)
manual, no check: 4 wallclock secs ( 2.94 usr + 0.00 sys = 2.94 CPU) @ 680272.11/s (n=2000000)
### But how long does it take to load the modules?
$ time -p perl -MMoo -e 1
real 0.03
user 0.02
sys 0.00
$ time -p perl -MMoos -e 1
real 0.03
user 0.02
sys 0.00
$ time -p perl -MMoose -e 1
real 0.31
user 0.29
sys 0.02
$ time -p perl -MMouse -e 1
real 0.04
user 0.02
sys 0.01
### And how long would it take to create a number of accessors you might
### actually use in a single CGI request? Let's try 1,000 instead of 2 million
### In this case, all options handle the task basically instantly, so the differences
### don't matter. It's the startup/initial load time that dominates.
Testing Perl 5.014002, Moose 2.0603, Mouse 0.99, Moo 1.000003
Benchmark: timing 1000 iterations of Moo, Moo w/quote_sub, Moose, Mouse, hash, hash, no check, manual, manual, no check...
Moo: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 100000.00/s (n=1000)
(warning: too few iterations for a reliable count)
Moo w/quote_sub: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 100000.00/s (n=1000)
(warning: too few iterations for a reliable count)
Moose: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
Mouse: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
hash: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
hash, no check: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
manual: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
manual, no check: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(warning: too few iterations for a reliable count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment