1Type::Tiny::Manual::OptUismeirzaCtoinotnr(i3b)uted PerlTDyopceu:m:eTnitnayt:i:oMnanual::Optimization(3)
2
3
4

NAME

6       Type::Tiny::Manual::Optimization - squeeze the most out of your CPU
7

DESCRIPTION

9       Various tips to help you squeeze the most out of your CPU.
10
11   XS
12       The simplest thing you can do to increase performance of many of the
13       built-in type constraints is to install Type::Tiny::XS, a set of ultra-
14       fast type constraint checks implemented in C.
15
16       Type::Tiny will attempt to load Type::Tiny::XS and use its type checks.
17       If Type::Tiny::XS is not available, it will then try to use Mouse if it
18       is already loaded, but Type::Tiny won't attempt to load Mouse for you.
19
20       Types that can be accelerated by Type::Tiny::XS
21
22       The following simple type constraints from Types::Standard will be
23       accelerated by Type::Tiny::XS: "Any", "ArrayRef", "Bool", "ClassName",
24       "CodeRef", "Defined", "FileHandle", "GlobRef", "HashRef", "Int",
25       "Item", "Object", "Map", "Ref", "ScalarRef", "Str", "Tuple", "Undef",
26       and "Value". (Note that "Num" and "RegexpRef" are not on that list.)
27
28       The parameterized form of "Ref" cannot be accelerated.
29
30       The parameterized forms of "ArrayRef", "HashRef", and "Map" can be
31       accelerated only if their parameters are.
32
33       The parameterized form of "Tuple" can be accelerated if its parameters
34       are, it has no "Optional" components, and it does not use "slurpy".
35
36       Certain type constraints may benefit partially from Type::Tiny::XS.
37       For example, "RoleName" inherits from "ClassName", so part of the type
38       check will be conducted by Type::Tiny::XS.
39
40       The parameterized "InstanceOf", "HasMethods", and "Enum" type
41       constraints will be accelerated. So will Type::Tiny::Class,
42       Type::Tiny::Duck, and Type::Tiny::Enum objects. (But enums will only be
43       accelerated if the list of allowed string values consist entirely of
44       word characters and hyphens - that is: "not grep /[^\w-]/, @values".)
45
46       The "PositiveInt" and "PositiveOrZeroInt" type constraints from
47       Types::Common::Numeric will be accelerated, as will the "NonEmptyStr"
48       type constraint from Types::Common::String.
49
50       Type::Tiny::Union and Type::Tiny::Intersection will also be accelerated
51       if their constituent type constraints are.
52
53       Types that can be accelerated by Mouse
54
55       The following simple type constraints from Types::Standard will be
56       accelerated by Type::Tiny::XS: "Any", "ArrayRef", "Bool", "ClassName",
57       "CodeRef", "Defined", "FileHandle", "GlobRef", "HashRef", "Ref",
58       "ScalarRef", "Str", "Undef", and "Value".  (Note that "Item", "Num",
59       "Int", "Object", and "RegexpRef" are not on that list.)
60
61       The parameterized form of "Ref" cannot be accelerated.
62
63       The parameterized forms of "ArrayRef" and "HashRef" can be accelerated
64       only if their parameters are.
65
66       Certain type constraints may benefit partially from Mouse. For example,
67       "RoleName" inherits from "ClassName", so part of the type check will be
68       conducted by Mouse.
69
70       The parameterized "InstanceOf" and "HasMethods" type constraints will
71       be accelerated. So will Type::Tiny::Class and Type::Tiny::Duck objects.
72
73   Common Sense
74       The "HashRef[ArrayRef]" type constraint can probably be checked faster
75       than "HashRef[ArrayRef[Num]]". If you find yourself using very complex
76       and slow type constraints, you should consider switching to simpler and
77       faster ones. (Though this means you have to place a little more trust
78       in your caller to not supply you with bad data.)
79
80       (A counter-intuitive exception to this: even though "Int" is more
81       restrictive than "Num", in most circumstances "Int" checks will run
82       faster.)
83
84   Inlining Type Constraints
85       If your type constraint can be inlined, this can not only speed up
86       Type::Tiny's own checks and coercions, it may also allow your type
87       constraint to be inlined into generated methods such as Moose attribute
88       accessors.
89
90       All of the constraints from "Types::Standard" can be inlined, as can
91       enum, class_type, role_type and duck_type constraints. Union and
92       intersection constraints can be inlined if their sub-constraints can
93       be. So if you can define your own types purely in terms of these types,
94       you automatically get inlining:
95
96          declare HashLike, as union [
97             Ref["HASH"],
98             Overload["&{}"],
99          ];
100
101       However, sometimes these base types are not powerful enough and you'll
102       need to write a constraint coderef:
103
104          declare NonEmptyHash, as HashLike,
105             where     { scalar values %$_ };
106
107       ... and you've suddenly sacrificed a lot of speed.
108
109       Inlining to the rescue! You can define an inlining coderef which will
110       be passed two parameters: the constraint itself and a variable name as
111       a string.  For example, the variable name might be '$_' or '$_[0]'.
112       Your coderef should return a Perl expression string, interpolating that
113       variable name.
114
115          declare NonEmptyHash, as HashLike,
116             where     { scalar values %$_ },
117             inline_as {
118                my ($constraint, $varname) = @_;
119                return sprintf(
120                   '%s and scalar values %%{%s}',
121                   $constraint->parent->inline_check($varname),
122                   $varname,
123                );
124             };
125
126       The Perl expression could be inlined within a function or a "if" clause
127       or potentially anywhere, so it really must be an expression, not a
128       statement.  It should not "return" or "exit" and probably shouldn't
129       "die". (If you need loops and so on, you can output a "do" block.)
130
131       Note that if you're subtyping an existing type constraint, your
132       "inline_as" block is also responsible for checking the parent type's
133       constraint. This can be done quite easily, as shown in the example
134       above.
135
136       Note that defining a type constraint in terms of a constraint coderef
137       and an inlining coderef can be a little repetitive. Sub::Quote provides
138       an alternative that reduces repetition (though the inlined code might
139       not be as compact/good/fast).
140
141          declare NonEmptyHash, as HashLike,
142             constraint => quote_sub q{ scalar values %$_ };
143
144       Aside: it's been pointed out that "might not be as fast" above is a bit
145       hand-wavy. When Type::Tiny does inlining from Sub::Quote coderefs, it
146       needs to inline all the ancestor type constraints, and smush them
147       together with "&&". This may result in duplicate checks. For example,
148       if 'MyArray' inherits from 'MyRef' which inherits from 'MyDef', the
149       inlined code might end up as:
150
151          defined($_)              # check MyDef
152          && ref($_)               # check MyRef
153          && ref($_) eq 'ARRAY'    # check MyArray
154
155       When just the last check would have been sufficient. A custom
156       "inline_as" allows you finer control over how the type constraint is
157       inlined.
158
159   Optimizing Coercions
160       Coercions are often defined using coderefs:
161
162          PathTiny->plus_coercions(
163             Str,   sub { "Path::Tiny"->new($_) },
164             Undef, sub { "Path::Tiny"->new("/etc/myapp/default.conf") },
165          );
166
167       But you can instead define them as strings of Perl code operating on
168       $_:
169
170          PathTiny->plus_coercions(
171             Str,   q{ "Path::Tiny"->new($_) },
172             Undef, q{ "Path::Tiny"->new("/etc/myapp/default.conf") },
173          );
174
175       The latter will run faster, so is preferable at least for simple
176       coercions.
177
178       This makes the most difference when used with Moo, which supports
179       inlining of coercions. Moose does not inline coercions, but providing
180       coercions as strings still allows Type::Tiny to optimize the coercion
181       coderef it provides to Moose.
182

AUTHOR

184       Toby Inkster <tobyink@cpan.org>.
185
187       This software is copyright (c) 2013-2014, 2017-2019 by Toby Inkster.
188
189       This is free software; you can redistribute it and/or modify it under
190       the same terms as the Perl 5 programming language system itself.
191

DISCLAIMER OF WARRANTIES

193       THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
194       WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
195       MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
196
197
198
199perl v5.28.1                      2019-01-08Type::Tiny::Manual::Optimization(3)
Impressum