\x89\x50\x4E\x47\x0D\x0A\x1A\x0A PNG  \x89\x50\x4E\x47\x0D\x0A\x1A\x0A =pod =for stopwords smush smushed enums =encoding utf-8 =head1 NAME Type::Tiny::Manual::Optimization - squeeze the most out of your CPU =head1 DESCRIPTION Various tips to help you squeeze the most out of your CPU. =head2 XS The simplest thing you can do to increase performance of many of the built-in type constraints is to install L, a set of ultra-fast type constraint checks implemented in C. L will attempt to load L and use its type checks. If L is not available, it will then try to use L B<< if it is already loaded >>, but Type::Tiny won't attempt to load Mouse for you. =head3 Types that can be accelerated by Type::Tiny::XS The following simple type constraints from L will be accelerated by Type::Tiny::XS: C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, and C. (Note that C and C are B on that list.) The parameterized form of C cannot be accelerated. The parameterized forms of C, C, and C can be accelerated only if their parameters are. The parameterized form of C can be accelerated if its parameters are, it has no C components, and it does not use C. Certain type constraints may benefit partially from Type::Tiny::XS. For example, C inherits from C, so part of the type check will be conducted by Type::Tiny::XS. The parameterized C, C, and C type constraints will be accelerated. So will L, L, and L objects. (But enums will only be accelerated if the list of allowed string values consist entirely of word characters and hyphens - that is: C<< not grep /[^\w-]/, @values >>.) The C and C type constraints from L will be accelerated, as will the C type constraint from L. L and L will also be accelerated if their constituent type constraints are. =head3 Types that can be accelerated by Mouse The following simple type constraints from L will be accelerated by Type::Tiny::XS: C, C, C, C, C, C, C, C, C, C, C, C, C, and C. (Note that C, C, C, C, and C are B on that list.) The parameterized form of C cannot be accelerated. The parameterized forms of C and C can be accelerated only if their parameters are. Certain type constraints may benefit partially from Mouse. For example, C inherits from C, so part of the type check will be conducted by Mouse. The parameterized C and C type constraints will be accelerated. So will L and L objects. =head2 Common Sense The C<< HashRef[ArrayRef] >> type constraint can probably be checked faster than C<< HashRef[ArrayRef[Num]] >>. If you find yourself using very complex and slow type constraints, you should consider switching to simpler and faster ones. (Though this means you have to place a little more trust in your caller to not supply you with bad data.) (A counter-intuitive exception to this: even though C is more restrictive than C, in most circumstances C checks will run faster.) =head2 Inlining Type Constraints If your type constraint can be inlined, this can not only speed up Type::Tiny's own checks and coercions, it may also allow your type constraint to be inlined into generated methods such as Moose attribute accessors. All of the constraints from C can be inlined, as can enum, class_type, role_type and duck_type constraints. Union and intersection constraints can be inlined if their sub-constraints can be. So if you can define your own types purely in terms of these types, you automatically get inlining: declare HashLike, as union [ Ref["HASH"], Overload["&{}"], ]; However, sometimes these base types are not powerful enough and you'll need to write a constraint coderef: declare NonEmptyHash, as HashLike, where { scalar values %$_ }; ... and you've suddenly sacrificed a lot of speed. Inlining to the rescue! You can define an inlining coderef which will be passed two parameters: the constraint itself and a variable name as a string. For example, the variable name might be C<< '$_' >> or C<< '$_[0]' >>. Your coderef should return a Perl expression string, interpolating that variable name. declare NonEmptyHash, as HashLike, where { scalar values %$_ }, inline_as { my ($constraint, $varname) = @_; return sprintf( '%s and scalar values %%{%s}', $constraint->parent->inline_check($varname), $varname, ); }; The Perl expression could be inlined within a function or a C clause or potentially anywhere, so it really must be an expression, not a statement. It should not C or C and probably shouldn't C. (If you need loops and so on, you can output a C block.) Note that if you're subtyping an existing type constraint, your C block is also responsible for checking the parent type's constraint. This can be done quite easily, as shown in the example above. Note that defining a type constraint in terms of a constraint coderef and an inlining coderef can be a little repetitive. L provides an alternative that reduces repetition (though the inlined code might not be as compact/good/fast). declare NonEmptyHash, as HashLike, constraint => quote_sub q{ scalar values %$_ }; Aside: it's been pointed out that "might not be as fast" above is a bit hand-wavy. When Type::Tiny does inlining from Sub::Quote coderefs, it needs to inline all the ancestor type constraints, and smush them together with C<< && >>. This may result in duplicate checks. For example, if 'MyArray' inherits from 'MyRef' which inherits from 'MyDef', the inlined code might end up as: defined($_) # check MyDef && ref($_) # check MyRef && ref($_) eq 'ARRAY' # check MyArray When just the last check would have been sufficient. A custom C allows you finer control over how the type constraint is inlined. =head2 Optimizing Coercions Coercions are often defined using coderefs: PathTiny->plus_coercions( Str, sub { "Path::Tiny"->new($_) }, Undef, sub { "Path::Tiny"->new("/etc/myapp/default.conf") }, ); But you can instead define them as strings of Perl code operating on C<< $_ >>: PathTiny->plus_coercions( Str, q{ "Path::Tiny"->new($_) }, Undef, q{ "Path::Tiny"->new("/etc/myapp/default.conf") }, ); The latter will run faster, so is preferable at least for simple coercions. This makes the most difference when used with L, which supports inlining of coercions. L does not inline coercions, but providing coercions as strings still allows Type::Tiny to optimize the coercion coderef it provides to Moose. =head1 AUTHOR Toby Inkster Etobyink@cpan.orgE. =head1 COPYRIGHT AND LICENCE This software is copyright (c) 2013-2014, 2017-2019 by Toby Inkster. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTIES THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. =cut