-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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