June 2011 Archives

Moose 2.02

| No TrackBacks

It's almost July, which means that it's time to start looking at the next major release of Moose, 2.0200. In addition to the changes that have been released in the minor revisions of the 2.00 series, this release will also include some additional, larger changes, the main ones being type constraint inlining and some changes to the way we generate inlined methods.

Type constraint inlining

When you define a type, you typically only specify how the type differs from some parent type. Currently, as a way to speed up type constraint checking, you can use the optimize_as option to define a validation subroutine to be used in place of checking the parent constraint followed by the current constraint's check. This helps, but could be better.

In 2.02, you will be able to use the inline_as option instead, to define a code snippet to use when inlining this type constraint, avoiding even the subroutine call overhead in accessors and constructors. Based on some simple benchmarks, this speeds up accessors by 30-40% and constructors by 10-30%, depending on the type constraints used and what else the methods are doing:

Moose 2.00
------
Benchmark: timing 500000 iterations of accessors_simple, constructor_simple...
accessors_simple:  4 wallclock secs ( 4.41 usr +  0.00 sys =  4.41 CPU) @ 113378.68/s (n=500000)
constructor_simple: 18 wallclock secs (17.83 usr +  0.01 sys = 17.84 CPU) @ 28026.91/s (n=500000)
Benchmark: timing 20000 iterations of accessors_all, constructor_all...
accessors_all: 12 wallclock secs (11.92 usr +  0.01 sys = 11.93 CPU) @ 1676.45/s (n=20000)
constructor_all: 12 wallclock secs (11.85 usr +  0.01 sys = 11.86 CPU) @ 1686.34/s (n=20000)

Moose 2.02
-----
Benchmark: timing 500000 iterations of accessors_simple, constructor_simple...
accessors_simple:  3 wallclock secs ( 2.70 usr +  0.01 sys =  2.71 CPU) @ 184501.85/s (n=500000)
constructor_simple: 15 wallclock secs (16.15 usr +  0.00 sys = 16.15 CPU) @ 30959.75/s (n=500000)
Benchmark: timing 20000 iterations of accessors_all, constructor_all...
accessors_all:  8 wallclock secs ( 7.45 usr +  0.01 sys =  7.46 CPU) @ 2680.97/s (n=20000)
constructor_all:  8 wallclock secs ( 7.73 usr +  0.01 sys =  7.74 CPU) @ 2583.98/s (n=20000)

Because inline_as provides all of the functionality that optimize_as provided, optimize_as will be deprecated in 2.02, and eventually removed.

Method generation

Constructors and accessors are generated as closures. For instance, when you pass "default => sub { ... }" as an attribute option, that sub is saved, and then closed over when the accessor is generated (if the attribute is lazy), something along the lines of:

my $default = $attr->default;
my $code = eval "sub { ... }"; # this uses $default
$meta->add_method($attr->name => $code);

Previously, we used to close over a lot of meta-objects directly, out of convenience, but this makes deparsing hard because of the many links metaobjects have between each other (try using Data::Dump::Streamer to deparse a Moose-generated constructor!). More importantly though, this gets in the way of some future optimizations we're hoping to be able to do.

The actual effects of this are mostly only visible if you're writing extensions that require using the closed-over variables that were removed ($attr, $meta, $type_constraint_obj, etc). If you were, you'll have to either adjust your inlining code to use the new variables that are provided, or override the environment that Moose uses when compiling generated methods to add them back. Feel free to stop by #moose if you have questions about how to do this.

Finally, one obstacle to this being complete is that initializer subs receive the attribute metaobject as a parameter, which means we can't avoid closing over it in that case. This behavior is now deprecated, and will be removed in the future.

Other changes since 2.0008

  • The Array native trait now has a first_index delegation, which works just like first except that it returns the index of the match rather than the match itself.

Summary of changes during the 2.00 release cycle

  • Type constraint error messages now use Devel::PartialDump when possible, to display the data that failed the type constraint.
  • Anonymous packages are now possible, via Class::MOP::Package->create_anon.
  • The methods we generate are now much better about storing definition contexts, so there should be a lot fewer instances of "generated method (unknown origin)".
  • Many bug fixes (see the Changes file for a full list).

Conclusion

Please install the current release candidate (Moose 2.0102) from CPAN, and report any issues it causes with your code. If all goes well, Moose 2.0200 will be released on July 18.

About this Archive

This page is an archive of entries from June 2011 listed from newest to oldest.

May 2011 is the previous archive.

December 2011 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Powered by Movable Type 4.38