| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Role/Tiny.pm |
| Statements | Executed 5347 statements in 13.6ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 2 | 1 | 1 | 4.20ms | 5.55ms | Role::Tiny::_load_module |
| 603 | 1 | 1 | 1.95ms | 2.34ms | Role::Tiny::does_role |
| 24 | 4 | 2 | 1.14ms | 1.28ms | Role::Tiny::_all_subs |
| 12 | 1 | 1 | 700µs | 2.94ms | Role::Tiny::_install_methods |
| 12 | 3 | 3 | 550µs | 15.4ms | Role::Tiny::apply_roles_to_package |
| 79 | 5 | 5 | 342µs | 1.09ms | JSON::Schema::Modern::Vocabulary::Core::DOES |
| 12 | 2 | 2 | 285µs | 545µs | Role::Tiny::_install_does |
| 19 | 2 | 1 | 279µs | 12.0ms | Role::Tiny::_check_roles |
| 148 | 5 | 1 | 256µs | 256µs | Role::Tiny::_getglob |
| 79 | 5 | 5 | 223µs | 542µs | JSON::Schema::Modern::Vocabulary::Content::DOES |
| 79 | 5 | 5 | 205µs | 553µs | JSON::Schema::Modern::Vocabulary::Applicator::DOES |
| 79 | 5 | 5 | 195µs | 588µs | JSON::Schema::Modern::Vocabulary::FormatAnnotation::DOES |
| 76 | 5 | 5 | 185µs | 475µs | JSON::Schema::Modern::Vocabulary::Unevaluated::DOES |
| 79 | 5 | 5 | 183µs | 628µs | JSON::Schema::Modern::Vocabulary::Validation::DOES |
| 79 | 5 | 5 | 179µs | 557µs | JSON::Schema::Modern::Vocabulary::MetaData::DOES |
| 93 | 8 | 3 | 177µs | 177µs | Role::Tiny::is_role |
| 12 | 1 | 1 | 124µs | 622µs | Role::Tiny::_concrete_methods_of |
| 567 | 3 | 1 | 105µs | 105µs | Role::Tiny::CORE:match (opcode) |
| 4 | 1 | 1 | 99µs | 356µs | Role::Tiny::make_role |
| 7 | 1 | 1 | 95µs | 3.72ms | Role::Tiny::create_class_with_roles |
| 12 | 1 | 1 | 83µs | 96µs | Role::Tiny::_check_requires |
| 26 | 2 | 1 | 81µs | 81µs | Role::Tiny::_getstash |
| 4 | 3 | 3 | 80µs | 1.09ms | Role::Tiny::import |
| 2 | 1 | 1 | 55µs | 126µs | Role::Tiny::_install_subs |
| 8 | 3 | 2 | 54µs | 54µs | Role::Tiny::_non_methods |
| 5 | 3 | 3 | 52µs | 78µs | JSON::Schema::Modern::Vocabulary::OpenAPI::DOES |
| 12 | 1 | 1 | 52µs | 52µs | Role::Tiny::_copy_applied_list |
| 7 | 1 | 1 | 50µs | 3.77ms | Role::Tiny::apply_roles_to_object |
| 12 | 1 | 1 | 40µs | 661µs | Role::Tiny::_install_modifiers |
| 1 | 1 | 1 | 34µs | 37µs | Role::Tiny::BEGIN@2 |
| 12 | 1 | 1 | 34µs | 36µs | Role::Tiny::_want_backcompat_hack |
| 2 | 1 | 1 | 33µs | 33µs | Role::Tiny::_gen_subs |
| 7 | 1 | 1 | 27µs | 27µs | Role::Tiny::_composite_name |
| 2 | 1 | 1 | 24µs | 24µs | Role::Tiny::CORE:subst (opcode) |
| 1 | 1 | 1 | 24µs | 1.15ms | Role::Tiny::_build_class_with_roles |
| 12 | 2 | 2 | 24µs | 24µs | Role::Tiny::role_application_steps |
| 2 | 1 | 1 | 13µs | 5.57ms | Role::Tiny::_require_module |
| 1 | 1 | 1 | 10µs | 17µs | Role::Tiny::BEGIN@24 |
| 1 | 1 | 1 | 10µs | 31µs | Role::Tiny::BEGIN@484 |
| 1 | 1 | 1 | 8µs | 12µs | Role::Tiny::BEGIN@65 |
| 1 | 1 | 1 | 7µs | 7µs | Role::Tiny::BEGIN@16 |
| 1 | 1 | 1 | 7µs | 19µs | Role::Tiny::BEGIN@242 |
| 1 | 1 | 1 | 6µs | 9µs | Role::Tiny::BEGIN@25 |
| 1 | 1 | 1 | 6µs | 54µs | Role::Tiny::BEGIN@3 |
| 1 | 1 | 1 | 5µs | 10µs | JSON::Schema::Modern::Vocabulary::FormatAssertion::DOES |
| 1 | 1 | 1 | 5µs | 30µs | Role::Tiny::BEGIN@29 |
| 2 | 1 | 1 | 5µs | 5µs | Role::Tiny::CORE:sort (opcode) |
| 0 | 0 | 0 | 0s | 0s | Method::Generate::Accessor__WITH__MooX::TypeTiny::Role::GenerateAccessor::DOES |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__ANON__[:145] |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__ANON__[:150] |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__ANON__[:154] |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__ANON__[:465] |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__ANON__[:483] |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::__GUARD__::DESTROY |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::_composite_info_for |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::_install_single_modifier |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::_mark_new_non_methods |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::apply_role_to_package |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::apply_single_role_to_package |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::croak |
| 0 | 0 | 0 | 0s | 0s | Role::Tiny::methods_provided_by |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Role::Tiny; | ||||
| 2 | 2 | 45µs | 2 | 40µs | # spent 37µs (34+3) within Role::Tiny::BEGIN@2 which was called:
# once (34µs+3µs) by Mojo::Base::BEGIN@17 at line 2 # spent 37µs making 1 call to Role::Tiny::BEGIN@2
# spent 3µs making 1 call to strict::import |
| 3 | 2 | 341µs | 2 | 102µs | # spent 54µs (6+48) within Role::Tiny::BEGIN@3 which was called:
# once (6µs+48µs) by Mojo::Base::BEGIN@17 at line 3 # spent 54µs making 1 call to Role::Tiny::BEGIN@3
# spent 48µs making 1 call to warnings::import |
| 4 | |||||
| 5 | 1 | 1µs | our $VERSION = '2.002004'; | ||
| 6 | 1 | 2µs | $VERSION =~ tr/_//d; | ||
| 7 | |||||
| 8 | our %INFO; | ||||
| 9 | our %APPLIED_TO; | ||||
| 10 | our %COMPOSED; | ||||
| 11 | our %COMPOSITE_INFO; | ||||
| 12 | our @ON_ROLE_CREATE; | ||||
| 13 | |||||
| 14 | # Module state workaround totally stolen from Zefram's Module::Runtime. | ||||
| 15 | |||||
| 16 | # spent 7µs within Role::Tiny::BEGIN@16 which was called:
# once (7µs+0s) by Mojo::Base::BEGIN@17 at line 22 | ||||
| 17 | 1 | 3µs | *_WORK_AROUND_BROKEN_MODULE_STATE = "$]" < 5.009 ? sub(){1} : sub(){0}; | ||
| 18 | *_WORK_AROUND_HINT_LEAKAGE | ||||
| 19 | = "$]" < 5.011 && !("$]" >= 5.009004 && "$]" < 5.010001) | ||||
| 20 | 1 | 0s | ? sub(){1} : sub(){0}; | ||
| 21 | 1 | 5µs | *_CONSTANTS_DEFLATE = "$]" >= 5.012 && "$]" < 5.020 ? sub(){1} : sub(){0}; | ||
| 22 | 1 | 34µs | 1 | 7µs | } # spent 7µs making 1 call to Role::Tiny::BEGIN@16 |
| 23 | |||||
| 24 | 150 | 447µs | 2 | 24µs | # spent 256µs within Role::Tiny::_getglob which was called 148 times, avg 2µs/call:
# 123 times (206µs+0s) by Role::Tiny::_install_methods at line 411, avg 2µs/call
# 12 times (13µs+0s) by Role::Tiny::_install_does at line 485, avg 1µs/call
# 10 times (28µs+0s) by Role::Tiny::_install_subs at line 131, avg 3µs/call
# 2 times (0s+0s) by Role::Tiny::_install_does at line 474, avg 0s/call
# once (9µs+0s) by Role::Tiny::_build_class_with_roles at line 215
# spent 17µs (10+7) within Role::Tiny::BEGIN@24 which was called:
# once (10µs+7µs) by Mojo::Base::BEGIN@17 at line 24 # spent 17µs making 1 call to Role::Tiny::BEGIN@24
# spent 7µs making 1 call to strict::unimport |
| 25 | 28 | 156µs | 2 | 12µs | # spent 9µs (6+3) within Role::Tiny::BEGIN@25 which was called:
# once (6µs+3µs) by Mojo::Base::BEGIN@17 at line 25
# spent 81µs within Role::Tiny::_getstash which was called 26 times, avg 3µs/call:
# 24 times (68µs+0s) by Role::Tiny::_all_subs at line 62, avg 3µs/call
# 2 times (13µs+0s) by Role::Tiny::_load_module at line 47, avg 6µs/call # spent 9µs making 1 call to Role::Tiny::BEGIN@25
# spent 3µs making 1 call to strict::unimport |
| 26 | |||||
| 27 | sub croak { | ||||
| 28 | require Carp; | ||||
| 29 | 2 | 253µs | 2 | 55µs | # spent 30µs (5+25) within Role::Tiny::BEGIN@29 which was called:
# once (5µs+25µs) by Mojo::Base::BEGIN@17 at line 29 # spent 30µs making 1 call to Role::Tiny::BEGIN@29
# spent 25µs making 1 call to warnings::unimport |
| 30 | *croak = \&Carp::croak; | ||||
| 31 | goto &Carp::croak; | ||||
| 32 | } | ||||
| 33 | |||||
| 34 | sub Role::Tiny::__GUARD__::DESTROY { | ||||
| 35 | delete $INC{$_[0]->[0]} if @{$_[0]}; | ||||
| 36 | } | ||||
| 37 | |||||
| 38 | # spent 5.55ms (4.20+1.35) within Role::Tiny::_load_module which was called 2 times, avg 2.78ms/call:
# 2 times (4.20ms+1.35ms) by Role::Tiny::_require_module at line 57, avg 2.78ms/call | ||||
| 39 | 2 | 1µs | my ($module) = @_; | ||
| 40 | 2 | 39µs | 2 | 24µs | (my $file = "$module.pm") =~ s{::}{/}g; # spent 24µs making 2 calls to Role::Tiny::CORE:subst, avg 12µs/call |
| 41 | return 1 | ||||
| 42 | 2 | 1µs | if $INC{$file}; | ||
| 43 | |||||
| 44 | # can't just ->can('can') because a sub-package Foo::Bar::Baz | ||||
| 45 | # creates a 'Baz::' key in Foo::Bar's symbol table | ||||
| 46 | return 1 | ||||
| 47 | 2 | 5µs | 2 | 13µs | if grep !/::\z/, keys %{_getstash($module)}; # spent 13µs making 2 calls to Role::Tiny::_getstash, avg 6µs/call |
| 48 | 2 | 2µs | my $guard = _WORK_AROUND_BROKEN_MODULE_STATE | ||
| 49 | && bless([ $file ], 'Role::Tiny::__GUARD__'); | ||||
| 50 | local %^H if _WORK_AROUND_HINT_LEAKAGE; | ||||
| 51 | 2 | 1.33ms | require $file; | ||
| 52 | pop @$guard if _WORK_AROUND_BROKEN_MODULE_STATE; | ||||
| 53 | 2 | 13µs | return 1; | ||
| 54 | } | ||||
| 55 | |||||
| 56 | # spent 5.57ms (13µs+5.55) within Role::Tiny::_require_module which was called 2 times, avg 2.78ms/call:
# 2 times (13µs+5.55ms) by Role::Tiny::_check_roles at line 231, avg 2.78ms/call | ||||
| 57 | 2 | 9µs | 2 | 5.55ms | _load_module($_[1]); # spent 5.55ms making 2 calls to Role::Tiny::_load_module, avg 2.78ms/call |
| 58 | } | ||||
| 59 | |||||
| 60 | # spent 1.28ms (1.14+145µs) within Role::Tiny::_all_subs which was called 24 times, avg 53µs/call:
# 12 times (583µs+76µs) by Role::Tiny::_install_methods at line 401, avg 55µs/call
# 4 times (273µs+22µs) by Role::Tiny::_concrete_methods_of at line 375, avg 74µs/call
# 4 times (185µs+20µs) by Role::Tiny::make_role at line 115, avg 51µs/call
# 4 times (97µs+27µs) by Moo::Role::_non_methods at line 150 of Moo/Role.pm, avg 31µs/call | ||||
| 61 | 24 | 12µs | my ($me, $package) = @_; | ||
| 62 | 24 | 66µs | 24 | 68µs | my $stash = _getstash($package); # spent 68µs making 24 calls to Role::Tiny::_getstash, avg 3µs/call |
| 63 | return { | ||||
| 64 | map {; | ||||
| 65 | 2 | 711µs | 2 | 16µs | # spent 12µs (8+4) within Role::Tiny::BEGIN@65 which was called:
# once (8µs+4µs) by Mojo::Base::BEGIN@17 at line 65 # spent 12µs making 1 call to Role::Tiny::BEGIN@65
# spent 4µs making 1 call to strict::unimport |
| 66 | # this is an ugly hack to populate the scalar slot of any globs, to | ||||
| 67 | # prevent perl from converting constants back into scalar refs in the | ||||
| 68 | # stash when they are used (perl 5.12 - 5.18). scalar slots on their own | ||||
| 69 | # aren't detectable through pure perl, so this seems like an acceptable | ||||
| 70 | # compromise. | ||||
| 71 | ${"${package}::${_}"} = ${"${package}::${_}"} | ||||
| 72 | if _CONSTANTS_DEFLATE; | ||||
| 73 | 292 | 193µs | $_ => \&{"${package}::${_}"} | ||
| 74 | } | ||||
| 75 | 24 | 965µs | 420 | 77µs | grep exists &{"${package}::${_}"}, # spent 77µs making 420 calls to Role::Tiny::CORE:match, avg 183ns/call |
| 76 | grep !/::\z/, | ||||
| 77 | keys %$stash | ||||
| 78 | }; | ||||
| 79 | } | ||||
| 80 | |||||
| 81 | # spent 1.09ms (80µs+1.01) within Role::Tiny::import which was called 4 times, avg 272µs/call:
# 2 times (43µs+685µs) by JSON::Schema::Modern::Vocabulary::BEGIN@10 or MooX::TypeTiny::Role::GenerateAccessor::BEGIN@2 at line 55 of Moo/Role.pm, avg 364µs/call
# once (24µs+220µs) by Data::Perl::Role::Collection::Array::BEGIN@7 at line 7 of Data/Perl/Role/Collection/Array.pm
# once (13µs+103µs) by Data::Perl::Role::Collection::Hash::BEGIN@7 at line 7 of Data/Perl/Role/Collection/Hash.pm | ||||
| 82 | 4 | 1µs | my $target = caller; | ||
| 83 | 4 | 1µs | my $me = shift; | ||
| 84 | 4 | 22µs | 4 | 9µs | strict->import; # spent 9µs making 4 calls to strict::import, avg 2µs/call |
| 85 | 4 | 4µs | 4 | 87µs | warnings->import; # spent 87µs making 4 calls to warnings::import, avg 22µs/call |
| 86 | 4 | 13µs | 4 | 107µs | my $non_methods = $me->_non_methods($target); # spent 101µs making 2 calls to Moo::Role::_non_methods, avg 50µs/call
# spent 6µs making 2 calls to Role::Tiny::_non_methods, avg 3µs/call |
| 87 | 4 | 7µs | 4 | 449µs | $me->_install_subs($target, @_); # spent 323µs making 2 calls to Moo::Role::_install_subs, avg 162µs/call
# spent 126µs making 2 calls to Role::Tiny::_install_subs, avg 63µs/call |
| 88 | 4 | 10µs | 4 | 356µs | $me->make_role($target); # spent 356µs making 4 calls to Role::Tiny::make_role, avg 89µs/call |
| 89 | 4 | 4µs | $me->_mark_new_non_methods($target, $non_methods) | ||
| 90 | if $non_methods && %$non_methods; | ||||
| 91 | 4 | 17µs | return; | ||
| 92 | } | ||||
| 93 | |||||
| 94 | sub _mark_new_non_methods { | ||||
| 95 | my ($me, $target, $old_non_methods) = @_; | ||||
| 96 | |||||
| 97 | my $non_methods = $INFO{$target}{non_methods}; | ||||
| 98 | |||||
| 99 | my $subs = $me->_all_subs($target); | ||||
| 100 | for my $sub (keys %$subs) { | ||||
| 101 | if ( exists $old_non_methods->{$sub} && $non_methods->{$sub} != $subs->{$sub} ) { | ||||
| 102 | $non_methods->{$sub} = $subs->{$sub}; | ||||
| 103 | } | ||||
| 104 | } | ||||
| 105 | |||||
| 106 | return; | ||||
| 107 | } | ||||
| 108 | |||||
| 109 | # spent 356µs (99+257) within Role::Tiny::make_role which was called 4 times, avg 89µs/call:
# 4 times (99µs+257µs) by Role::Tiny::import at line 88, avg 89µs/call | ||||
| 110 | 4 | 3µs | my ($me, $target) = @_; | ||
| 111 | |||||
| 112 | 4 | 3µs | 4 | 34µs | return if $me->is_role($target); # spent 33µs making 2 calls to Moo::Role::is_role, avg 16µs/call
# spent 1µs making 2 calls to Role::Tiny::is_role, avg 500ns/call |
| 113 | 4 | 6µs | $INFO{$target}{is_role} = 1; | ||
| 114 | |||||
| 115 | 4 | 8µs | 4 | 205µs | my $non_methods = $me->_all_subs($target); # spent 205µs making 4 calls to Role::Tiny::_all_subs, avg 51µs/call |
| 116 | 4 | 43µs | 24 | 4µs | delete @{$non_methods}{grep /\A\(/, keys %$non_methods}; # spent 4µs making 24 calls to Role::Tiny::CORE:match, avg 167ns/call |
| 117 | 4 | 3µs | $INFO{$target}{non_methods} = $non_methods; | ||
| 118 | |||||
| 119 | # a role does itself | ||||
| 120 | 4 | 5µs | $APPLIED_TO{$target} = { $target => undef }; | ||
| 121 | 4 | 13µs | foreach my $hook (@ON_ROLE_CREATE) { | ||
| 122 | 4 | 13µs | 4 | 14µs | $hook->($target); # spent 14µs making 4 calls to Moo::Role::__ANON__[Moo/Role.pm:123], avg 4µs/call |
| 123 | } | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | # spent 126µs (55+71) within Role::Tiny::_install_subs which was called 2 times, avg 63µs/call:
# 2 times (55µs+71µs) by Role::Tiny::import at line 87, avg 63µs/call | ||||
| 127 | 2 | 1µs | my ($me, $target) = @_; | ||
| 128 | 2 | 5µs | 2 | 5µs | return if $me->is_role($target); # spent 5µs making 2 calls to Role::Tiny::is_role, avg 2µs/call |
| 129 | 2 | 9µs | 2 | 33µs | my %install = $me->_gen_subs($target); # spent 33µs making 2 calls to Role::Tiny::_gen_subs, avg 16µs/call |
| 130 | *{_getglob("${target}::${_}")} = $install{$_} | ||||
| 131 | 2 | 29µs | 12 | 33µs | for sort keys %install; # spent 28µs making 10 calls to Role::Tiny::_getglob, avg 3µs/call
# spent 5µs making 2 calls to Role::Tiny::CORE:sort, avg 2µs/call |
| 132 | 2 | 4µs | return; | ||
| 133 | } | ||||
| 134 | |||||
| 135 | # spent 33µs within Role::Tiny::_gen_subs which was called 2 times, avg 16µs/call:
# 2 times (33µs+0s) by Role::Tiny::_install_subs at line 129, avg 16µs/call | ||||
| 136 | 2 | 1µs | my ($me, $target) = @_; | ||
| 137 | ( | ||||
| 138 | (map {; | ||||
| 139 | 6 | 2µs | my $type = $_; | ||
| 140 | $type => sub { | ||||
| 141 | my $code = pop; | ||||
| 142 | my @names = ref $_[0] eq 'ARRAY' ? @{ $_[0] } : @_; | ||||
| 143 | push @{$INFO{$target}{modifiers}||=[]}, [ $type, @names, $code ]; | ||||
| 144 | return; | ||||
| 145 | 6 | 8µs | }; | ||
| 146 | } qw(before after around)), | ||||
| 147 | requires => sub { | ||||
| 148 | push @{$INFO{$target}{requires}||=[]}, @_; | ||||
| 149 | return; | ||||
| 150 | }, | ||||
| 151 | with => sub { | ||||
| 152 | $me->apply_roles_to_package($target, @_); | ||||
| 153 | return; | ||||
| 154 | }, | ||||
| 155 | 2 | 26µs | ); | ||
| 156 | } | ||||
| 157 | |||||
| 158 | # spent 24µs within Role::Tiny::role_application_steps which was called 12 times, avg 2µs/call:
# 10 times (19µs+0s) by Moo::Role::role_application_steps at line 294 of Moo/Role.pm, avg 2µs/call
# 2 times (5µs+0s) by Role::Tiny::apply_roles_to_package at line 301, avg 2µs/call | ||||
| 159 | 12 | 32µs | qw( | ||
| 160 | _install_methods | ||||
| 161 | _check_requires | ||||
| 162 | _install_modifiers | ||||
| 163 | _copy_applied_list | ||||
| 164 | ); | ||||
| 165 | } | ||||
| 166 | |||||
| 167 | # spent 52µs within Role::Tiny::_copy_applied_list which was called 12 times, avg 4µs/call:
# 12 times (52µs+0s) by Role::Tiny::apply_roles_to_package at line 312, avg 4µs/call | ||||
| 168 | 12 | 6µs | my ($me, $to, $role) = @_; | ||
| 169 | # copy our role list into the target's | ||||
| 170 | 12 | 57µs | @{$APPLIED_TO{$to}||={}}{keys %{$APPLIED_TO{$role}}} = (); | ||
| 171 | } | ||||
| 172 | |||||
| 173 | # spent 3.77ms (50µs+3.72) within Role::Tiny::apply_roles_to_object which was called 7 times, avg 538µs/call:
# 7 times (50µs+3.72ms) by Moo::Role::apply_roles_to_object at line 376 of Moo/Role.pm, avg 538µs/call | ||||
| 174 | 7 | 3µs | my ($me, $object, @roles) = @_; | ||
| 175 | 7 | 5µs | my $class = ref($object); | ||
| 176 | # on perl < 5.8.9, magic isn't copied to all ref copies. bless the parameter | ||||
| 177 | # directly, so at least the variable passed to us will get any magic applied | ||||
| 178 | 7 | 37µs | 7 | 3.72ms | bless($_[1], $me->create_class_with_roles($class, @roles)); # spent 3.72ms making 7 calls to Role::Tiny::create_class_with_roles, avg 531µs/call |
| 179 | } | ||||
| 180 | |||||
| 181 | 1 | 0s | my $role_suffix = 'A000'; | ||
| 182 | # spent 27µs within Role::Tiny::_composite_name which was called 7 times, avg 4µs/call:
# 7 times (27µs+0s) by Role::Tiny::create_class_with_roles at line 203, avg 4µs/call | ||||
| 183 | 7 | 3µs | my ($me, $superclass, @roles) = @_; | ||
| 184 | |||||
| 185 | 7 | 8µs | my $new_name = $superclass . '__WITH__' . join '__AND__', @roles; | ||
| 186 | |||||
| 187 | 7 | 5µs | if (length($new_name) > 252) { | ||
| 188 | $new_name = $COMPOSED{abbrev}{$new_name} ||= do { | ||||
| 189 | my $abbrev = substr $new_name, 0, 250 - length $role_suffix; | ||||
| 190 | $abbrev =~ s/(?<!:):$//; | ||||
| 191 | $abbrev.'__'.$role_suffix++; | ||||
| 192 | }; | ||||
| 193 | } | ||||
| 194 | 7 | 16µs | return $new_name; | ||
| 195 | } | ||||
| 196 | |||||
| 197 | # spent 3.72ms (95µs+3.62) within Role::Tiny::create_class_with_roles which was called 7 times, avg 531µs/call:
# 7 times (95µs+3.62ms) by Role::Tiny::apply_roles_to_object at line 178, avg 531µs/call | ||||
| 198 | 7 | 2µs | my ($me, $superclass, @roles) = @_; | ||
| 199 | |||||
| 200 | 7 | 16µs | 7 | 157µs | $me->_require_module($superclass); # spent 157µs making 7 calls to Moo::Role::_require_module, avg 22µs/call |
| 201 | 7 | 19µs | 7 | 2.23ms | $me->_check_roles(@roles); # spent 2.23ms making 7 calls to Role::Tiny::_check_roles, avg 319µs/call |
| 202 | |||||
| 203 | 7 | 16µs | 7 | 27µs | my $new_name = $me->_composite_name($superclass, @roles); # spent 27µs making 7 calls to Role::Tiny::_composite_name, avg 4µs/call |
| 204 | |||||
| 205 | return $new_name | ||||
| 206 | 7 | 23µs | if $COMPOSED{class}{$new_name}; | ||
| 207 | |||||
| 208 | 1 | 6µs | 1 | 1.20ms | return $me->_build_class_with_roles($new_name, $superclass, @roles); # spent 1.20ms making 1 call to Moo::Role::_build_class_with_roles |
| 209 | } | ||||
| 210 | |||||
| 211 | # spent 1.15ms (24µs+1.13) within Role::Tiny::_build_class_with_roles which was called:
# once (24µs+1.13ms) by Moo::Role::_build_class_with_roles at line 301 of Moo/Role.pm | ||||
| 212 | 1 | 1µs | my ($me, $new_name, $superclass, @roles) = @_; | ||
| 213 | |||||
| 214 | 1 | 2µs | $COMPOSED{base}{$new_name} = $superclass; | ||
| 215 | 1 | 10µs | 1 | 9µs | @{*{_getglob("${new_name}::ISA")}} = ( $superclass ); # spent 9µs making 1 call to Role::Tiny::_getglob |
| 216 | 1 | 4µs | 1 | 1.12ms | $me->apply_roles_to_package($new_name, @roles); # spent 1.12ms making 1 call to Role::Tiny::apply_roles_to_package |
| 217 | 1 | 1µs | $COMPOSED{class}{$new_name} = 1; | ||
| 218 | 1 | 3µs | return $new_name; | ||
| 219 | } | ||||
| 220 | |||||
| 221 | sub _check_roles { | ||||
| 222 | 19 | 12µs | my ($me, @roles) = @_; | ||
| 223 | 19 | 7µs | croak "No roles supplied!" unless @roles; | ||
| 224 | |||||
| 225 | 19 | 3µs | my %seen; | ||
| 226 | 19 | 45µs | if (my @dupes = grep 1 == $seen{$_}++, @roles) { | ||
| 227 | croak "Duplicated roles: ".join(', ', @dupes); | ||||
| 228 | } | ||||
| 229 | |||||
| 230 | 19 | 61µs | foreach my $role (@roles) { | ||
| 231 | 19 | 45µs | 19 | 11.4ms | $me->_require_module($role); # spent 5.81ms making 17 calls to Moo::Role::_require_module, avg 342µs/call
# spent 5.57ms making 2 calls to Role::Tiny::_require_module, avg 2.78ms/call |
| 232 | 19 | 51µs | 19 | 319µs | croak "${role} is not a ${me}" unless $me->is_role($role); # spent 309µs making 17 calls to Moo::Role::is_role, avg 18µs/call
# spent 10µs making 2 calls to Role::Tiny::is_role, avg 5µs/call |
| 233 | } | ||||
| 234 | } | ||||
| 235 | |||||
| 236 | our %BACKCOMPAT_HACK; | ||||
| 237 | 1 | 1µs | $BACKCOMPAT_HACK{+__PACKAGE__} = 0; | ||
| 238 | # spent 36µs (34+2) within Role::Tiny::_want_backcompat_hack which was called 12 times, avg 3µs/call:
# 12 times (34µs+2µs) by Role::Tiny::apply_roles_to_package at line 293, avg 3µs/call | ||||
| 239 | 12 | 6µs | my $me = shift; | ||
| 240 | return $BACKCOMPAT_HACK{$me} | ||||
| 241 | 12 | 31µs | if exists $BACKCOMPAT_HACK{$me}; | ||
| 242 | 2 | 1.50ms | 2 | 31µs | # spent 19µs (7+12) within Role::Tiny::BEGIN@242 which was called:
# once (7µs+12µs) by Mojo::Base::BEGIN@17 at line 242 # spent 19µs making 1 call to Role::Tiny::BEGIN@242
# spent 12µs making 1 call to warnings::unimport |
| 243 | 1 | 9µs | 1 | 2µs | $BACKCOMPAT_HACK{$me} = # spent 2µs making 1 call to UNIVERSAL::can |
| 244 | $me->can('apply_single_role_to_package') != \&apply_single_role_to_package | ||||
| 245 | && $me->can('role_application_steps') == \&role_application_steps | ||||
| 246 | } | ||||
| 247 | |||||
| 248 | our $IN_APPLY_ROLES; | ||||
| 249 | sub apply_single_role_to_package { | ||||
| 250 | return | ||||
| 251 | if $IN_APPLY_ROLES; | ||||
| 252 | local $IN_APPLY_ROLES = 1; | ||||
| 253 | |||||
| 254 | my ($me, $to, $role) = @_; | ||||
| 255 | $me->apply_roles_to_package($to, $role); | ||||
| 256 | } | ||||
| 257 | |||||
| 258 | sub apply_role_to_package { | ||||
| 259 | my ($me, $to, $role) = @_; | ||||
| 260 | $me->apply_roles_to_package($to, $role); | ||||
| 261 | } | ||||
| 262 | |||||
| 263 | # spent 15.4ms (550µs+14.8) within Role::Tiny::apply_roles_to_package which was called 12 times, avg 1.28ms/call:
# 9 times (424µs+7.32ms) by Moo::with at line 104 of Moo.pm, avg 860µs/call
# 2 times (64µs+6.46ms) by Role::Tiny::With::with at line 16 of Role/Tiny/With.pm, avg 3.26ms/call
# once (62µs+1.06ms) by Role::Tiny::_build_class_with_roles at line 216 | ||||
| 264 | 12 | 10µs | my ($me, $to, @roles) = @_; | ||
| 265 | 12 | 9µs | croak "Can't apply roles to object with apply_roles_to_package" | ||
| 266 | if ref $to; | ||||
| 267 | |||||
| 268 | 12 | 33µs | 12 | 9.74ms | $me->_check_roles(@roles); # spent 9.74ms making 12 calls to Role::Tiny::_check_roles, avg 811µs/call |
| 269 | |||||
| 270 | 12 | 1µs | my @have_conflicts; | ||
| 271 | my %role_methods; | ||||
| 272 | |||||
| 273 | 12 | 6µs | if (@roles > 1) { | ||
| 274 | my %conflicts = %{$me->_composite_info_for(@roles)->{conflicts}}; | ||||
| 275 | @have_conflicts = grep $to->can($_), keys %conflicts; | ||||
| 276 | delete @conflicts{@have_conflicts}; | ||||
| 277 | |||||
| 278 | if (keys %conflicts) { | ||||
| 279 | my $class = $COMPOSED{base}{$to} || $to; | ||||
| 280 | my $fail = | ||||
| 281 | join "\n", | ||||
| 282 | map { | ||||
| 283 | "Due to a method name conflict between roles " | ||||
| 284 | .join(' and ', map "'$_'", sort values %{$conflicts{$_}}) | ||||
| 285 | .", the method '$_' must be implemented by '$class'" | ||||
| 286 | } sort keys %conflicts; | ||||
| 287 | croak $fail; | ||||
| 288 | } | ||||
| 289 | |||||
| 290 | %role_methods = map +($_ => $me->_concrete_methods_of($_)), @roles; | ||||
| 291 | } | ||||
| 292 | |||||
| 293 | 12 | 19µs | 12 | 36µs | if (!$IN_APPLY_ROLES and _want_backcompat_hack($me)) { # spent 36µs making 12 calls to Role::Tiny::_want_backcompat_hack, avg 3µs/call |
| 294 | local $IN_APPLY_ROLES = 1; | ||||
| 295 | foreach my $role (@roles) { | ||||
| 296 | $me->apply_single_role_to_package($to, $role); | ||||
| 297 | } | ||||
| 298 | } | ||||
| 299 | |||||
| 300 | 12 | 10µs | my $role_methods; | ||
| 301 | 12 | 25µs | 12 | 67µs | foreach my $step ($me->role_application_steps) { # spent 62µs making 10 calls to Moo::Role::role_application_steps, avg 6µs/call
# spent 5µs making 2 calls to Role::Tiny::role_application_steps, avg 2µs/call |
| 302 | 78 | 98µs | foreach my $role (@roles) { | ||
| 303 | # conflicting methods are supposed to be treated as required by the | ||||
| 304 | # composed role. we don't have an actual composed role, but because | ||||
| 305 | # we know the target class already provides them, we can instead | ||||
| 306 | # pretend that the roles don't do for the duration of application. | ||||
| 307 | $role_methods = $role_methods{$role} and ( | ||||
| 308 | (local @{$role_methods}{@have_conflicts}), | ||||
| 309 | 78 | 23µs | (delete @{$role_methods}{@have_conflicts}), | ||
| 310 | ); | ||||
| 311 | |||||
| 312 | 78 | 174µs | 78 | 4.99ms | $me->$step($to, $role); # spent 2.94ms making 12 calls to Role::Tiny::_install_methods, avg 245µs/call
# spent 852µs making 10 calls to Moo::Role::_undefer_subs, avg 85µs/call
# spent 661µs making 12 calls to Role::Tiny::_install_modifiers, avg 55µs/call
# spent 355µs making 10 calls to Moo::Role::_maybe_make_accessors, avg 36µs/call
# spent 96µs making 12 calls to Role::Tiny::_check_requires, avg 8µs/call
# spent 52µs making 12 calls to Role::Tiny::_copy_applied_list, avg 4µs/call
# spent 28µs making 10 calls to Moo::Role::_handle_constructor, avg 3µs/call |
| 313 | } | ||||
| 314 | } | ||||
| 315 | 12 | 53µs | $APPLIED_TO{$to}{join('|',@roles)} = 1; | ||
| 316 | } | ||||
| 317 | |||||
| 318 | sub _composite_info_for { | ||||
| 319 | my ($me, @roles) = @_; | ||||
| 320 | $COMPOSITE_INFO{join('|', sort @roles)} ||= do { | ||||
| 321 | my %methods; | ||||
| 322 | foreach my $role (@roles) { | ||||
| 323 | my $this_methods = $me->_concrete_methods_of($role); | ||||
| 324 | $methods{$_}{$this_methods->{$_}} = $role for keys %$this_methods; | ||||
| 325 | } | ||||
| 326 | delete $methods{$_} for grep keys(%{$methods{$_}}) == 1, keys %methods; | ||||
| 327 | +{ conflicts => \%methods } | ||||
| 328 | }; | ||||
| 329 | } | ||||
| 330 | |||||
| 331 | # spent 96µs (83+13) within Role::Tiny::_check_requires which was called 12 times, avg 8µs/call:
# 12 times (83µs+13µs) by Role::Tiny::apply_roles_to_package at line 312, avg 8µs/call | ||||
| 332 | 12 | 8µs | my ($me, $to, $name, $requires) = @_; | ||
| 333 | 12 | 12µs | $requires ||= $INFO{$name}{requires} || []; | ||
| 334 | 12 | 96µs | 18 | 13µs | if (my @requires_fail = grep !$to->can($_), @$requires) { # spent 13µs making 18 calls to UNIVERSAL::can, avg 722ns/call |
| 335 | # role -> role, add to requires, role -> class, error out | ||||
| 336 | if (my $to_info = $INFO{$to}) { | ||||
| 337 | push @{$to_info->{requires}||=[]}, @requires_fail; | ||||
| 338 | } else { | ||||
| 339 | croak "Can't apply ${name} to ${to} - missing ".join(', ', @requires_fail); | ||||
| 340 | } | ||||
| 341 | } | ||||
| 342 | } | ||||
| 343 | |||||
| 344 | # spent 54µs within Role::Tiny::_non_methods which was called 8 times, avg 7µs/call:
# 4 times (32µs+0s) by Moo::Role::_non_methods at line 148 of Moo/Role.pm, avg 8µs/call
# 2 times (16µs+0s) by Role::Tiny::_concrete_methods_of at line 373, avg 8µs/call
# 2 times (6µs+0s) by Role::Tiny::import at line 86, avg 3µs/call | ||||
| 345 | 8 | 8µs | my ($me, $role) = @_; | ||
| 346 | 8 | 21µs | my $info = $INFO{$role} or return {}; | ||
| 347 | |||||
| 348 | 4 | 16µs | my %non_methods = %{ $info->{non_methods} || {} }; | ||
| 349 | |||||
| 350 | # this is only for backwards compatibility with older Moo, which | ||||
| 351 | # reimplements method tracking rather than calling our method | ||||
| 352 | 4 | 8µs | my %not_methods = reverse %{ $info->{not_methods} || {} }; | ||
| 353 | 4 | 11µs | return \%non_methods unless keys %not_methods; | ||
| 354 | |||||
| 355 | my $subs = $me->_all_subs($role); | ||||
| 356 | for my $sub (grep !/\A\(/, keys %$subs) { | ||||
| 357 | my $code = $subs->{$sub}; | ||||
| 358 | if (exists $not_methods{$code}) { | ||||
| 359 | $non_methods{$sub} = $code; | ||||
| 360 | } | ||||
| 361 | } | ||||
| 362 | |||||
| 363 | return \%non_methods; | ||||
| 364 | } | ||||
| 365 | |||||
| 366 | # spent 622µs (124+498) within Role::Tiny::_concrete_methods_of which was called 12 times, avg 52µs/call:
# 12 times (124µs+498µs) by Role::Tiny::_install_methods at line 398, avg 52µs/call | ||||
| 367 | 12 | 8µs | my ($me, $role) = @_; | ||
| 368 | 12 | 5µs | my $info = $INFO{$role}; | ||
| 369 | |||||
| 370 | return $info->{methods} | ||||
| 371 | 12 | 21µs | if $info && $info->{methods}; | ||
| 372 | |||||
| 373 | 4 | 7µs | 4 | 203µs | my $non_methods = $me->_non_methods($role); # spent 187µs making 2 calls to Moo::Role::_non_methods, avg 94µs/call
# spent 16µs making 2 calls to Role::Tiny::_non_methods, avg 8µs/call |
| 374 | |||||
| 375 | 4 | 8µs | 4 | 295µs | my $subs = $me->_all_subs($role); # spent 295µs making 4 calls to Role::Tiny::_all_subs, avg 74µs/call |
| 376 | 4 | 9µs | for my $sub (keys %$subs) { | ||
| 377 | 84 | 37µs | if ( exists $non_methods->{$sub} && $non_methods->{$sub} == $subs->{$sub} ) { | ||
| 378 | delete $subs->{$sub}; | ||||
| 379 | } | ||||
| 380 | } | ||||
| 381 | |||||
| 382 | 4 | 5µs | if ($info) { | ||
| 383 | $info->{methods} = $subs; | ||||
| 384 | } | ||||
| 385 | 4 | 14µs | return $subs; | ||
| 386 | } | ||||
| 387 | |||||
| 388 | sub methods_provided_by { | ||||
| 389 | my ($me, $role) = @_; | ||||
| 390 | $me->_require_module($role); | ||||
| 391 | croak "${role} is not a ${me}" unless $me->is_role($role); | ||||
| 392 | sort (keys %{$me->_concrete_methods_of($role)}, @{$INFO{$role}->{requires}||[]}); | ||||
| 393 | } | ||||
| 394 | |||||
| 395 | # spent 2.94ms (700µs+2.24) within Role::Tiny::_install_methods which was called 12 times, avg 245µs/call:
# 12 times (700µs+2.24ms) by Role::Tiny::apply_roles_to_package at line 312, avg 245µs/call | ||||
| 396 | 12 | 8µs | my ($me, $to, $role) = @_; | ||
| 397 | |||||
| 398 | 12 | 27µs | 12 | 622µs | my $methods = $me->_concrete_methods_of($role); # spent 622µs making 12 calls to Role::Tiny::_concrete_methods_of, avg 52µs/call |
| 399 | |||||
| 400 | 12 | 9µs | my %existing_methods; | ||
| 401 | 12 | 72µs | 12 | 659µs | @existing_methods{keys %{ $me->_all_subs($to) }} = (); # spent 659µs making 12 calls to Role::Tiny::_all_subs, avg 55µs/call |
| 402 | |||||
| 403 | # _concrete_methods_of caches its result on roles. that cache needs to be | ||||
| 404 | # invalidated after applying roles | ||||
| 405 | 12 | 5µs | delete $INFO{$to}{methods} if $INFO{$to}; | ||
| 406 | |||||
| 407 | 12 | 58µs | foreach my $i (keys %$methods) { | ||
| 408 | next | ||||
| 409 | 131 | 20µs | if exists $existing_methods{$i}; | ||
| 410 | |||||
| 411 | 123 | 134µs | 123 | 206µs | my $glob = _getglob "${to}::${i}"; # spent 206µs making 123 calls to Role::Tiny::_getglob, avg 2µs/call |
| 412 | 123 | 73µs | *$glob = $methods->{$i}; | ||
| 413 | |||||
| 414 | # overloads using method names have the method stored in the scalar slot | ||||
| 415 | # and &overload::nil in the code slot. | ||||
| 416 | next | ||||
| 417 | unless $i =~ /^\(/ | ||||
| 418 | && ((defined &overload::nil && $methods->{$i} == \&overload::nil) | ||||
| 419 | 123 | 163µs | 123 | 24µs | || (defined &overload::_nil && $methods->{$i} == \&overload::_nil)); # spent 24µs making 123 calls to Role::Tiny::CORE:match, avg 195ns/call |
| 420 | |||||
| 421 | my $overload = ${ _getglob "${role}::${i}" }; | ||||
| 422 | next | ||||
| 423 | unless defined $overload; | ||||
| 424 | |||||
| 425 | *$glob = \$overload; | ||||
| 426 | } | ||||
| 427 | |||||
| 428 | 12 | 56µs | 12 | 733µs | $me->_install_does($to); # spent 647µs making 10 calls to Moo::Role::_install_does, avg 65µs/call
# spent 86µs making 2 calls to Role::Tiny::_install_does, avg 43µs/call |
| 429 | } | ||||
| 430 | |||||
| 431 | # spent 661µs (40+621) within Role::Tiny::_install_modifiers which was called 12 times, avg 55µs/call:
# 12 times (40µs+621µs) by Role::Tiny::apply_roles_to_package at line 312, avg 55µs/call | ||||
| 432 | 12 | 7µs | my ($me, $to, $name) = @_; | ||
| 433 | 12 | 32µs | return unless my $modifiers = $INFO{$name}{modifiers}; | ||
| 434 | 1 | 0s | my $info = $INFO{$to}; | ||
| 435 | 1 | 2µs | my $existing = ($info ? $info->{modifiers} : $COMPOSED{modifiers}{$to}) ||= []; | ||
| 436 | my @modifiers = grep { | ||||
| 437 | 2 | 1µs | my $modifier = $_; | ||
| 438 | 2 | 0s | !grep $_ == $modifier, @$existing; | ||
| 439 | 1 | 2µs | } @{$modifiers||[]}; | ||
| 440 | 1 | 1µs | push @$existing, @modifiers; | ||
| 441 | |||||
| 442 | 1 | 5µs | if (!$info) { | ||
| 443 | foreach my $modifier (@modifiers) { | ||||
| 444 | 2 | 4µs | 2 | 621µs | $me->_install_single_modifier($to, @$modifier); # spent 621µs making 2 calls to Moo::Role::_install_single_modifier, avg 310µs/call |
| 445 | } | ||||
| 446 | } | ||||
| 447 | } | ||||
| 448 | |||||
| 449 | 1 | 0s | my $vcheck_error; | ||
| 450 | |||||
| 451 | sub _install_single_modifier { | ||||
| 452 | my ($me, @args) = @_; | ||||
| 453 | defined($vcheck_error) or $vcheck_error = do { | ||||
| 454 | local $@; | ||||
| 455 | eval { | ||||
| 456 | require Class::Method::Modifiers; | ||||
| 457 | Class::Method::Modifiers->VERSION(1.05); | ||||
| 458 | 1; | ||||
| 459 | } ? 0 : $@; | ||||
| 460 | }; | ||||
| 461 | $vcheck_error and die $vcheck_error; | ||||
| 462 | Class::Method::Modifiers::install_modifier(@args); | ||||
| 463 | } | ||||
| 464 | |||||
| 465 | 1 | 11µs | my $FALLBACK = sub { 0 }; | ||
| 466 | # spent 545µs (285+260) within Role::Tiny::_install_does which was called 12 times, avg 45µs/call:
# 10 times (219µs+240µs) by Moo::Role::_install_does at line 400 of Moo/Role.pm, avg 46µs/call
# 2 times (66µs+20µs) by Role::Tiny::_install_methods at line 428, avg 43µs/call | ||||
| 467 | 12 | 6µs | my ($me, $to) = @_; | ||
| 468 | |||||
| 469 | # only add does() method to classes | ||||
| 470 | 12 | 16µs | 12 | 158µs | return if $me->is_role($to); # spent 154µs making 10 calls to Moo::Role::is_role, avg 15µs/call
# spent 4µs making 2 calls to Role::Tiny::is_role, avg 2µs/call |
| 471 | |||||
| 472 | 12 | 49µs | 12 | 18µs | my $does = $me->can('does_role'); # spent 18µs making 12 calls to UNIVERSAL::can, avg 2µs/call |
| 473 | # add does() only if they don't have one | ||||
| 474 | 12 | 79µs | 14 | 27µs | *{_getglob "${to}::does"} = $does unless $to->can('does'); # spent 27µs making 12 calls to UNIVERSAL::can, avg 2µs/call
# spent 0s making 2 calls to Role::Tiny::_getglob, avg 0s/call |
| 475 | |||||
| 476 | return | ||||
| 477 | 12 | 92µs | 36 | 35µs | if $to->can('DOES') and $to->can('DOES') != (UNIVERSAL->can('DOES') || 0); # spent 35µs making 36 calls to UNIVERSAL::can, avg 972ns/call |
| 478 | |||||
| 479 | 12 | 32µs | 12 | 9µs | my $existing = $to->can('DOES') || $to->can('isa') || $FALLBACK; # spent 9µs making 12 calls to UNIVERSAL::can, avg 750ns/call |
| 480 | # spent 557µs (179+378) within JSON::Schema::Modern::Vocabulary::MetaData::DOES which was called 79 times, avg 7µs/call:
# 36 times (92µs+179µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 8µs/call
# 24 times (43µs+111µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 6µs/call
# 14 times (27µs+53µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 6µs/call
# 3 times (8µs+18µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 9µs/call
# 2 times (9µs+17µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 13µs/call
# spent 1.09ms (342µs+747µs) within JSON::Schema::Modern::Vocabulary::Core::DOES which was called 79 times, avg 14µs/call:
# 36 times (172µs+430µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 17µs/call
# 24 times (109µs+157µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 11µs/call
# 14 times (42µs+129µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 12µs/call
# 3 times (10µs+20µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 10µs/call
# 2 times (9µs+11µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 10µs/call
# spent 475µs (185+290) within JSON::Schema::Modern::Vocabulary::Unevaluated::DOES which was called 76 times, avg 6µs/call:
# 36 times (99µs+133µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 6µs/call
# 24 times (50µs+91µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 6µs/call
# 14 times (28µs+54µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 6µs/call
# once (6µs+7µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3]
# once (2µs+5µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3]
# spent 588µs (195+393) within JSON::Schema::Modern::Vocabulary::FormatAnnotation::DOES which was called 79 times, avg 7µs/call:
# 36 times (111µs+207µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 9µs/call
# 24 times (37µs+98µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 6µs/call
# 14 times (30µs+57µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 6µs/call
# 3 times (9µs+20µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 10µs/call
# 2 times (8µs+11µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 10µs/call
# spent 628µs (183+445) within JSON::Schema::Modern::Vocabulary::Validation::DOES which was called 79 times, avg 8µs/call:
# 36 times (89µs+250µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 9µs/call
# 24 times (49µs+91µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 6µs/call
# 14 times (28µs+71µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 7µs/call
# 3 times (8µs+21µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 10µs/call
# 2 times (9µs+12µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 10µs/call
# spent 553µs (205+348) within JSON::Schema::Modern::Vocabulary::Applicator::DOES which was called 79 times, avg 7µs/call:
# 36 times (90µs+170µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 7µs/call
# 24 times (42µs+96µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 6µs/call
# 14 times (29µs+57µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 6µs/call
# 3 times (6µs+13µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 6µs/call
# 2 times (38µs+12µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 25µs/call
# spent 78µs (52+26) within JSON::Schema::Modern::Vocabulary::OpenAPI::DOES which was called 5 times, avg 16µs/call:
# 2 times (28µs+8µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 18µs/call
# 2 times (19µs+7µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 13µs/call
# once (5µs+11µs) by Type::Tiny::__ANON__[(eval 419)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 419)[Sub/Quote.pm:3]
# spent 10µs (5+5) within JSON::Schema::Modern::Vocabulary::FormatAssertion::DOES which was called:
# once (5µs+5µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3]
# spent 542µs (223+319) within JSON::Schema::Modern::Vocabulary::Content::DOES which was called 79 times, avg 7µs/call:
# 36 times (99µs+157µs) by Type::Tiny::__ANON__[(eval 428)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 428)[Sub/Quote.pm:3], avg 7µs/call
# 24 times (41µs+87µs) by Type::Tiny::__ANON__[(eval 430)[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Sub/Quote.pm:3]:16] at line 16 of (eval 430)[Sub/Quote.pm:3], avg 5µs/call
# 14 times (35µs+52µs) by JSON::Schema::Modern::Document::_assert__path_to_resource at line 24 of (eval 299)[Sub/Quote.pm:3], avg 6µs/call
# 3 times (9µs+14µs) by JSON::Schema::Modern::_assert__metaschema_vocabulary_classes at line 24 of (eval 360)[Sub/Quote.pm:3], avg 8µs/call
# 2 times (39µs+9µs) by JSON::Schema::Modern::_assert__vocabulary_classes at line 24 of (eval 355)[Sub/Quote.pm:3], avg 24µs/call | ||||
| 481 | 556 | 236µs | my ($proto, $role) = @_; | ||
| 482 | 556 | 1.30ms | 556 | 2.95ms | $proto->$does($role) or $proto->$existing($role); # spent 2.95ms making 556 calls to Moo::Role::does_role, avg 5µs/call |
| 483 | 12 | 32µs | }; | ||
| 484 | 2 | 318µs | 2 | 52µs | # spent 31µs (10+21) within Role::Tiny::BEGIN@484 which was called:
# once (10µs+21µs) by Mojo::Base::BEGIN@17 at line 484 # spent 31µs making 1 call to Role::Tiny::BEGIN@484
# spent 21µs making 1 call to warnings::unimport |
| 485 | 12 | 52µs | 12 | 13µs | return *{_getglob "${to}::DOES"} = $new_sub; # spent 13µs making 12 calls to Role::Tiny::_getglob, avg 1µs/call |
| 486 | } | ||||
| 487 | |||||
| 488 | # optimize for newer perls | ||||
| 489 | require mro | ||||
| 490 | 1 | 3µs | if "$]" >= 5.009_005; | ||
| 491 | |||||
| 492 | 1 | 2µs | if (defined &mro::get_linear_isa) { | ||
| 493 | *_linear_isa = \&mro::get_linear_isa; | ||||
| 494 | } | ||||
| 495 | else { | ||||
| 496 | my $e; | ||||
| 497 | { | ||||
| 498 | local $@; | ||||
| 499 | # this routine is simplified and not fully compatible with mro::get_linear_isa | ||||
| 500 | # but for our use the order doesn't matter, so we don't need to care | ||||
| 501 | eval <<'END_CODE' or $e = $@; | ||||
| 502 | sub _linear_isa($;$) { | ||||
| 503 | if (defined &mro::get_linear_isa) { | ||||
| 504 | no warnings 'redefine', 'prototype'; | ||||
| 505 | *_linear_isa = \&mro::get_linear_isa; | ||||
| 506 | goto &mro::get_linear_isa; | ||||
| 507 | } | ||||
| 508 | |||||
| 509 | my @check = shift; | ||||
| 510 | my @lin; | ||||
| 511 | |||||
| 512 | my %found; | ||||
| 513 | while (defined(my $check = shift @check)) { | ||||
| 514 | push @lin, $check; | ||||
| 515 | no strict 'refs'; | ||||
| 516 | unshift @check, grep !$found{$_}++, @{"$check\::ISA"}; | ||||
| 517 | } | ||||
| 518 | |||||
| 519 | return \@lin; | ||||
| 520 | } | ||||
| 521 | |||||
| 522 | 1; | ||||
| 523 | END_CODE | ||||
| 524 | } | ||||
| 525 | die $e if defined $e; | ||||
| 526 | } | ||||
| 527 | |||||
| 528 | # spent 2.34ms (1.95+393µs) within Role::Tiny::does_role which was called 603 times, avg 4µs/call:
# 603 times (1.95ms+393µs) by Moo::Role::does_role at line 406 of Moo/Role.pm, avg 4µs/call | ||||
| 529 | 603 | 126µs | my ($proto, $role) = @_; | ||
| 530 | 603 | 1.40ms | 603 | 393µs | foreach my $class (@{_linear_isa(ref($proto)||$proto)}) { # spent 393µs making 603 calls to mro::get_linear_isa, avg 652ns/call |
| 531 | 610 | 1.18ms | return 1 if exists $APPLIED_TO{$class}{$role}; | ||
| 532 | } | ||||
| 533 | 7 | 19µs | return 0; | ||
| 534 | } | ||||
| 535 | |||||
| 536 | # spent 177µs within Role::Tiny::is_role which was called 93 times, avg 2µs/call:
# 34 times (80µs+0s) by Moo::Role::_inhale_if_moose at line 166 of Moo/Role.pm, avg 2µs/call
# 34 times (29µs+0s) by Moo::Role::is_role at line 160 of Moo/Role.pm, avg 853ns/call
# 15 times (42µs+0s) by Moo::import at line 40 of Moo.pm, avg 3µs/call
# 2 times (10µs+0s) by Role::Tiny::_check_roles at line 232, avg 5µs/call
# 2 times (6µs+0s) by Moo::_set_superclasses at line 149 of Moo.pm, avg 3µs/call
# 2 times (5µs+0s) by Role::Tiny::_install_subs at line 128, avg 2µs/call
# 2 times (4µs+0s) by Role::Tiny::_install_does at line 470, avg 2µs/call
# 2 times (1µs+0s) by Role::Tiny::make_role at line 112, avg 500ns/call | ||||
| 537 | 93 | 36µs | my ($me, $role) = @_; | ||
| 538 | return !!($INFO{$role} && ( | ||||
| 539 | $INFO{$role}{is_role} | ||||
| 540 | # these are for backward compatibility with older Moo that overrode some | ||||
| 541 | # methods without calling the originals, thus not getting is_role set | ||||
| 542 | || $INFO{$role}{requires} | ||||
| 543 | || $INFO{$role}{not_methods} | ||||
| 544 | || $INFO{$role}{non_methods} | ||||
| 545 | 93 | 247µs | )); | ||
| 546 | } | ||||
| 547 | |||||
| 548 | 1 | 10µs | 1; | ||
| 549 | __END__ | ||||
# spent 105µs within Role::Tiny::CORE:match which was called 567 times, avg 185ns/call:
# 420 times (77µs+0s) by Role::Tiny::_all_subs at line 75, avg 183ns/call
# 123 times (24µs+0s) by Role::Tiny::_install_methods at line 419, avg 195ns/call
# 24 times (4µs+0s) by Role::Tiny::make_role at line 116, avg 167ns/call | |||||
# spent 5µs within Role::Tiny::CORE:sort which was called 2 times, avg 2µs/call:
# 2 times (5µs+0s) by Role::Tiny::_install_subs at line 131, avg 2µs/call | |||||
# spent 24µs within Role::Tiny::CORE:subst which was called 2 times, avg 12µs/call:
# 2 times (24µs+0s) by Role::Tiny::_load_module at line 40, avg 12µs/call |