tags:

views:

348

answers:

3

I recently downloaded Moose. Experimentally, I rewrote an existing module in Moose. It seems to be convenient way to avoid writing lots of repetitive code. I ran the tests of the module, and I noticed it was a bit delayed. I profiled the code with -d:DProf and it seems that just including the line

no Moose;

in the code increases the running time by about 0.25 seconds (on my computer). Is this typical? Am I doing something wrong, did I misinstall it, or should we really expect this much delay?

+4  A: 

Your question is a little deceptive. Yes, Moose has a measurable startup cost, but isn't slow after that. If the startup cost is prohibitive, you can always daemonize your application.

ysth
Why is it deceptive? I had no idea Moose was this slow until yesterday, and I was fairly surprised by it.
Kinopiko
Also, in this case I cannot daemonize my application, and that would bring in a host of considerations like memory and file management.
Kinopiko
@Kinopiko, ysth is arguing the term `slow` hardly invokes "compile time" costs... You wouldn't say a KDE 4 is slow because it takes 9 hours to compile. And, you wouldn't say Linux is slow because of the time to run init scripts... I'm not agreeing with ysth, I'm just explaining what I believe is his argument.
Evan Carroll
@Kinopiko: if you look at the source for Moose::Meta::Class, Class::MOP::Class, Moose::Meta::Attribute and Class::MOP::Attribute you will not be surprised :)
Ether
You said it again: "Moose [is] slow"...*you* know you mean startup time, but someone else won't unless you clarify.
ysth
See for instance Ether's answer where s/he gives you advice that will make Moose faster at the expense of longer startup.
ysth
But I don't actually mean startup time. My whole program takes about 0.02 seconds to run to completion (i.e. finish what it's doing and exit). Hence 0.25 seconds is a lot.
Kinopiko
@Kinopiko - you're still talking about startup time (compile time) and the analogy still holds true: it takes 9 hours to compile KDE even if you just want to get on Konsole and find out the kernel version, which doesn't make KDE slow... Though you're arguing here that it is valid to say *KDE is slow* and leaving out *if all you want to is get at the kernel version on a fresh install*, other than not really having much to do with slow, it is hardly the normal use case for KDE anyway.
Evan Carroll
With Perl it's not possible to run a program without compiling it, so that is a poor analogy.
Kinopiko
I have to wonder why you are using OO at all for what sounds like a very procedural problem. :)
ysth
+12  A: 

Yes, there's a bit of a penalty to using Moose. However, it's only a startup penalty, not at runtime; if you wrote everything properly, then things will be quite fast at runtime.

Did you also include this line:

__PACKAGE__->meta->make_immutable;

in all your classes when you no Moose;? Calling this method will make it (runtime) faster (at the expense of startup time). In particular, object construction and destruction are effectively "inlined" in your class, and no longer invoke the meta API. It is strongly recommended that you make your classes immutable. It makes your code much faster, with a small compile-time cost. This will be especially noticeable when creating many objects.1 2

However, sometimes this cost is still too much. If you're using Moose inside a script, or in some other way where the compilation time is a significant fraction of your overall usage time, try doing s/Moose/Mouse/g -- if you don't use MooseX modules, you can likely switch to Mouse, whose goal is to be faster (at startup) while retaining 90% of the flexibility of Moose.

Since you are working with a web application, have you considered using mod_perl?

1From the docs of make_immutable, in Moose::Cookbook::Basics::Recipe7
2See also Stevan Little's article: Why make_immutable is recommended for Moose classes

Ether
Ether, I deleted all the other Moose stuff and just forgot to delete the final line "no Moose" and yet still got this 0.25 second delay. As for Mouse, how much faster is it?
Kinopiko
Sometimes much faster. There's rarely a good reason to *not* make your classes immutable (it's one of those things where you should only do so if you know why, and understand the drawbacks and ramifications.)
Ether
`$ time perl -Moose -E'has qw/foo isa Int is rw/; __PACKAGE__->meta->make_immutable if @ARGV; push @_, Class->new for 1..100_000; print scalar @_'`, then run the same thing just append a `1` as an argument. You could `use Benchmark(.pm)`, but sometimes it isn't even close.
Evan Carroll
Ether: Mouse's goal is to provide faster startup times, not to "be faster". A secondary (related!) goal is to have fewer dependencies.
ysth
Err, and make_immutable will AIUI make startup *slower* not faster.
ysth
@ysth; aye; I'll edit to make that more clear. immutability == slower startup but faster runtime; Mouse == faster startup, but less flexibility.
Ether
Actually Mouse's original goal was to teach Sartak how to write a Meta Protocol. Second to that was a low dep Moose without all the "Meta" overhead. Sartak then found that the "Meta" was the powerful part of Moose and moved on and someone else picked up Mouse.
perigrin
There are some MouseX modules to match MooseX modules, and some MooseX modules can be used with Mouse when you combine it with Any::Moose. It should also be noted that not only is Mouse faster to startup than Moose, it uses less memory. Part of Mouse's speed comes from it being partially implemented in XS (something we're still waiting for from Moose)
MkV
@MkV: some of Moose and Class::MOP is in XS.
Ether
Ether: yeah, but that is mostly for reasons of magic, not performance
MkV
+4  A: 

Using Moose pulls in a lot of stuff which needs to be compiled. Therefore, startup time is going to suffer. In that regard, Moose is no different than any other module with a lot of dependencies. Therefore, it would not be good choice to for a CGI application.

On the other hand, I am working on a web application which using Dancer and Moose. Because the application is running as an HTTPD daemon, none of this is really relevant once the server is initialized. Performance seems more than adequate for my requirements on limited hardware or virtual servers.

Using Moose and Dancer for this project has had the added benefit that my small demo application shrank from about 5,000 lines to less than 1,000 lines.

How much stuff you want your app to depend on is one of those trade-offs you have to consider. CGI apps are made more responsive by limiting dependencies.

On the other hand, most of my CGI scripts start with a sleep rand 3; ;-)

Sinan Ünür
+1 This is how I've been writing prototype or small web apps for past couple of years (except s/Dancer/Squatting/). Add a Reverse Proxy (http://en.wikipedia.org/wiki/Reverse_proxy) and never need to worry about CGI again :)
draegtun