The debate over whether or not Moose is too slow rumbles on. On one side, are the folks using it in production (and presumably happpy with it). On the other, are folks saying it adds multiple seconds to the start-up time.
Following on from my benchmarking Moose startup overhead post, Sue D. Nymme provided code that actually created an object. Thanks Sue!
I took a look and Sue’s code uses MooseX::Declare that I haven’t installed. One magic CPAN invocation and, oh my gosh, more than 20 minutes later, MooseX::Declare is finally installed. Now I’m thinking that the benchmark time is actually measuring the time for perl to load in and parse MooseX::Declare and tens of thousands of lines of prerequisites rather than how slow Moose itself is.
I’ll compare just loading the modules Moose vs MooseX::Declare.
Then I’ll add the rest of Sue’s code.
And finally I’ll actually create a Moose object.
just-moose.pl
use Modern::Perl; use Moose; use Moose::Util::TypeConstraints; use DateTime; 1;
all-includes.pl
use Modern::Perl; use MooseX::Declare; use Moose::Util::TypeConstraints; use DateTime; 1;
And moose.pl (taken from Sue D. Nymme’s comment here.
bench.pl
use Benchmark qw(:hireswallclock); use strict; use warnings; my $perl = 'c:/strawberry/perl/bin/perl'; Benchmark::timethese(200, { '1just-moose' => sub { system(qq{$perl -e "require 'just-moose.pl';"}) }, '2all-includes' => sub { system(qq{$perl -e "require 'all-includes.pl';"}) }, '3nocreate' => sub { system(qq{$perl -e "require 'moose.pl';"}) }, '4create' => sub { system(qq/$perl -e "require 'moose.pl'; MooseObject->new({ name => 'Bob' })"/) }, });
The Results
I’ve elided the too few iterations warnings.
Benchmark: timing 200 iterations of 1just-moose, 2all-includes, 3nocreate, 4create... 1just-moose: 100.196 wallclock secs ( 0.05 usr + 0.25 sys = 0.30 CPU) @ 673.40/s (n=200) 2all-includes: 279.252 wallclock secs ( 0.08 usr + 0.34 sys = 0.42 CPU) @ 475.06/s (n=200) 3nocreate: 318.256 wallclock secs ( 0.06 usr + 0.28 sys = 0.34 CPU) @ 581.40/s (n=200) 4create: 320.979 wallclock secs ( 0.06 usr + 0.27 sys = 0.33 CPU) @ 611.62/s (n=200)
Conclusions
The bulk of the time is in loading the MooseX::Declare library. But on the other hand, declaring a single object did take a significant amount of time (approximately 40 seconds over 200 runs). I can now believe that declaring a lot of objects would be prohibitively expensive.
But that is using MooseX::Declare. I’m sure it is nowhere near as bad if we used Plain Ole Moose.
Please, if you want to benchmark object creation, use Benchmark on the constructor call, not on the perl invocation + include loads + only one object creation.
Perhaps the construction overload is limited to the first invocation? I do not know Moose internals, but I think your conclusion is not fair.
Regards,
Max.
Please, “too few iterations” means exactly that. You cannot just ignore the warning, as the numbers have a good chance to be inaccurate. Run each benchmark item for 5 seconds or more.
Hi Jared,
my two cents — I have mid-sized application with almost 100 classes. Loading all of classes within 000_load.t with use_ok takes 18s on my development machine, which is about 0.2s for one file average.
Several simple tests alone (use/create instance/some simple operations) take about 0.5s to complete, compile and run.
I don’t have much issue with that, since it is web application running on Apache+mod_fastcgi. I typically have few instances running and the response averages ~ 70ms. Longer responses are usually problem of database backend.
One the other hand, I started with MooseX::Declare, but went back to plain Moose then, for two main reasons:
– for slightly nicer syntax you pay about 5x slower code
– The MooseX::Method::Signatures slow down method calls dramatically and validation messages it produces are mostly unreadable