| Filename | /Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm |
| Statements | Executed 4023 statements in 18.0ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 979 | 1 | 1 | 4.86ms | 84.6ms | Class::MOP::Method::Wrapped::__ANON__[:162] (recurses: max depth 3, inclusive time 613µs) |
| 67 | 2 | 1 | 3.53ms | 5.00ms | Class::MOP::Method::Wrapped::wrap |
| 65 | 1 | 1 | 457µs | 949µs | Class::MOP::Method::Wrapped::add_around_modifier |
| 65 | 1 | 1 | 340µs | 340µs | Class::MOP::Method::Wrapped::__ANON__[:164] |
| 135 | 4 | 1 | 340µs | 340µs | Class::MOP::Method::Wrapped::__ANON__[:71] |
| 67 | 1 | 1 | 313µs | 313µs | Class::MOP::Method::Wrapped::_new |
| 4 | 1 | 1 | 49µs | 199ms | Class::MOP::Method::Wrapped::__ANON__[:45] |
| 4 | 1 | 1 | 34µs | 2.18ms | Class::MOP::Method::Wrapped::__ANON__[:51] |
| 2 | 1 | 1 | 11µs | 22µs | Class::MOP::Method::Wrapped::add_before_modifier |
| 1 | 1 | 1 | 8µs | 8µs | Class::MOP::Method::Wrapped::BEGIN@3 |
| 1 | 1 | 1 | 6µs | 11µs | Class::MOP::Method::Wrapped::add_after_modifier |
| 1 | 1 | 1 | 6µs | 9µs | Class::MOP::Method::Wrapped::BEGIN@11 |
| 1 | 1 | 1 | 6µs | 16µs | Class::MOP::Method::Wrapped::BEGIN@10 |
| 1 | 1 | 1 | 6µs | 23µs | Class::MOP::Method::Wrapped::BEGIN@14 |
| 1 | 1 | 1 | 5µs | 26µs | Class::MOP::Method::Wrapped::BEGIN@13 |
| 1 | 1 | 1 | 5µs | 60µs | Class::MOP::Method::Wrapped::BEGIN@16 |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::__ANON__[:66] |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::__ANON__[:91] |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::_make_compatible_with |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::after_modifiers |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::around_modifiers |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::before_modifiers |
| 0 | 0 | 0 | 0s | 0s | Class::MOP::Method::Wrapped::get_original_method |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | |||||
| 2 | package Class::MOP::Method::Wrapped; | ||||
| 3 | # spent 8µs within Class::MOP::Method::Wrapped::BEGIN@3 which was called:
# once (8µs+0s) by Class::MOP::Class::BEGIN@14 at line 5 | ||||
| 4 | 1 | 4µs | $Class::MOP::Method::Wrapped::AUTHORITY = 'cpan:STEVAN'; | ||
| 5 | 1 | 29µs | 1 | 8µs | } # spent 8µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@3 |
| 6 | { | ||||
| 7 | 2 | 800ns | $Class::MOP::Method::Wrapped::VERSION = '2.1005'; | ||
| 8 | } | ||||
| 9 | |||||
| 10 | 2 | 20µs | 2 | 27µs | # spent 16µs (6+11) within Class::MOP::Method::Wrapped::BEGIN@10 which was called:
# once (6µs+11µs) by Class::MOP::Class::BEGIN@14 at line 10 # spent 16µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@10
# spent 11µs making 1 call to strict::import |
| 11 | 2 | 20µs | 2 | 12µs | # spent 9µs (6+3) within Class::MOP::Method::Wrapped::BEGIN@11 which was called:
# once (6µs+3µs) by Class::MOP::Class::BEGIN@14 at line 11 # spent 9µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@11
# spent 3µs making 1 call to warnings::import |
| 12 | |||||
| 13 | 2 | 20µs | 2 | 47µs | # spent 26µs (5+21) within Class::MOP::Method::Wrapped::BEGIN@13 which was called:
# once (5µs+21µs) by Class::MOP::Class::BEGIN@14 at line 13 # spent 26µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@13
# spent 21µs making 1 call to Exporter::import |
| 14 | 2 | 21µs | 2 | 41µs | # spent 23µs (6+18) within Class::MOP::Method::Wrapped::BEGIN@14 which was called:
# once (6µs+18µs) by Class::MOP::Class::BEGIN@14 at line 14 # spent 23µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@14
# spent 18µs making 1 call to Exporter::import |
| 15 | |||||
| 16 | 2 | 789µs | 2 | 114µs | # spent 60µs (5+54) within Class::MOP::Method::Wrapped::BEGIN@16 which was called:
# once (5µs+54µs) by Class::MOP::Class::BEGIN@14 at line 16 # spent 60µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@16
# spent 54µs making 1 call to base::import |
| 17 | |||||
| 18 | # NOTE: | ||||
| 19 | # this ugly beast is the result of trying | ||||
| 20 | # to micro optimize this as much as possible | ||||
| 21 | # while not completely loosing maintainability. | ||||
| 22 | # At this point it's "fast enough", after all | ||||
| 23 | # you can't get something for nothing :) | ||||
| 24 | # spent 340µs within Class::MOP::Method::Wrapped::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:71] which was called 135 times, avg 3µs/call:
# 67 times (173µs+0s) by Class::MOP::Method::Wrapped::wrap at line 89, avg 3µs/call
# 65 times (152µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 174, avg 2µs/call
# 2 times (11µs+0s) by Class::MOP::Method::Wrapped::add_before_modifier at line 131, avg 5µs/call
# once (5µs+0s) by Class::MOP::Method::Wrapped::add_after_modifier at line 143 | ||||
| 25 | 135 | 15µs | my $modifier_table = shift; | ||
| 26 | 135 | 65µs | my ($before, $after, $around) = ( | ||
| 27 | $modifier_table->{before}, | ||||
| 28 | $modifier_table->{after}, | ||||
| 29 | $modifier_table->{around}, | ||||
| 30 | ); | ||||
| 31 | 135 | 2.72ms | if (@$before && @$after) { | ||
| 32 | # spent 199ms (49µs+199) within Class::MOP::Method::Wrapped::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:45] which was called 4 times, avg 49.7ms/call:
# 4 times (49µs+199ms) by Moose::Meta::Class::__ANON__::SERIAL::1::install_accessors at line 91, avg 49.7ms/call | ||||
| 33 | 8 | 10µs | 4 | 149ms | for my $c (@$before) { $c->(@_) }; # spent 149ms making 4 calls to Class::MOP::Class:::before, avg 37.3ms/call |
| 34 | 4 | 400ns | my @rval; | ||
| 35 | 4 | 6µs | 4 | 49.5ms | ((defined wantarray) ? # spent 49.5ms making 4 calls to Moose::Meta::Attribute::install_accessors, avg 12.4ms/call |
| 36 | ((wantarray) ? | ||||
| 37 | (@rval = $around->{cache}->(@_)) | ||||
| 38 | : | ||||
| 39 | ($rval[0] = $around->{cache}->(@_))) | ||||
| 40 | : | ||||
| 41 | $around->{cache}->(@_)); | ||||
| 42 | 8 | 10µs | 4 | 24µs | for my $c (@$after) { $c->(@_) }; # spent 24µs making 4 calls to Class::MOP::Class:::after, avg 6µs/call |
| 43 | 4 | 10µs | return unless defined wantarray; | ||
| 44 | return wantarray ? @rval : $rval[0]; | ||||
| 45 | } | ||||
| 46 | 1 | 3µs | } | ||
| 47 | elsif (@$before && !@$after) { | ||||
| 48 | # spent 2.18ms (34µs+2.15) within Class::MOP::Method::Wrapped::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:51] which was called 4 times, avg 545µs/call:
# 4 times (34µs+2.15ms) by Moose::Meta::Class::__ANON__::SERIAL::1::_process_options at line 91, avg 545µs/call | ||||
| 49 | 8 | 13µs | 4 | 1.88ms | for my $c (@$before) { $c->(@_) }; # spent 1.88ms making 4 calls to Class::MOP::Class:::before, avg 469µs/call |
| 50 | 4 | 13µs | 4 | 271µs | return $around->{cache}->(@_); # spent 271µs making 4 calls to Moose::Meta::Attribute::_process_options, avg 68µs/call |
| 51 | } | ||||
| 52 | 2 | 6µs | } | ||
| 53 | elsif (@$after && !@$before) { | ||||
| 54 | $modifier_table->{cache} = sub { | ||||
| 55 | my @rval; | ||||
| 56 | ((defined wantarray) ? | ||||
| 57 | ((wantarray) ? | ||||
| 58 | (@rval = $around->{cache}->(@_)) | ||||
| 59 | : | ||||
| 60 | ($rval[0] = $around->{cache}->(@_))) | ||||
| 61 | : | ||||
| 62 | $around->{cache}->(@_)); | ||||
| 63 | for my $c (@$after) { $c->(@_) }; | ||||
| 64 | return unless defined wantarray; | ||||
| 65 | return wantarray ? @rval : $rval[0]; | ||||
| 66 | } | ||||
| 67 | } | ||||
| 68 | else { | ||||
| 69 | 132 | 40µs | $modifier_table->{cache} = $around->{cache}; | ||
| 70 | } | ||||
| 71 | 1 | 2µs | }; | ||
| 72 | |||||
| 73 | # spent 5.00ms (3.53+1.48) within Class::MOP::Method::Wrapped::wrap which was called 67 times, avg 75µs/call:
# 59 times (3.40ms+1.31ms) by Class::MOP::Class::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Class.pm:1072] at line 1058 of Class/MOP/Class.pm, avg 80µs/call
# 8 times (130µs+169µs) by Class::MOP::Class::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Class.pm:1072] at line 1065 of Class/MOP/Class.pm, avg 37µs/call | ||||
| 74 | 67 | 67µs | my ( $class, $code, %params ) = @_; | ||
| 75 | |||||
| 76 | 67 | 234µs | 134 | 61µs | (blessed($code) && $code->isa('Class::MOP::Method')) # spent 31µs making 67 calls to Scalar::Util::blessed, avg 461ns/call
# spent 30µs making 67 calls to UNIVERSAL::isa, avg 445ns/call |
| 77 | || confess "Can only wrap blessed CODE"; | ||||
| 78 | |||||
| 79 | 67 | 370µs | 134 | 51µs | my $modifier_table = { # spent 51µs making 134 calls to Class::MOP::Method::body, avg 381ns/call |
| 80 | cache => undef, | ||||
| 81 | orig => $code->body, | ||||
| 82 | before => [], | ||||
| 83 | after => [], | ||||
| 84 | around => { | ||||
| 85 | cache => $code->body, | ||||
| 86 | methods => [], | ||||
| 87 | }, | ||||
| 88 | }; | ||||
| 89 | 67 | 54µs | 67 | 173µs | $_build_wrapped_method->($modifier_table); # spent 173µs making 67 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71], avg 3µs/call |
| 90 | return $class->SUPER::wrap( | ||||
| 91 | 987 | 1.92ms | 987 | 286ms | sub { $modifier_table->{cache}->(@_) }, # spent 199ms making 4 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:45], avg 49.7ms/call
# spent 85.2ms making 979 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:162], avg 87µs/call, recursion: max depth 3, sum of overlapping time 613µs
# spent 2.18ms making 4 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:51], avg 545µs/call |
| 92 | # get these from the original | ||||
| 93 | # unless explicitly overridden | ||||
| 94 | 67 | 373µs | 67 | 1.19ms | package_name => $params{package_name} || $code->package_name, # spent 1.19ms making 67 calls to Class::MOP::Method::wrap, avg 18µs/call |
| 95 | name => $params{name} || $code->name, | ||||
| 96 | original_method => $code, | ||||
| 97 | |||||
| 98 | modifier_table => $modifier_table, | ||||
| 99 | ); | ||||
| 100 | } | ||||
| 101 | |||||
| 102 | # spent 313µs within Class::MOP::Method::Wrapped::_new which was called 67 times, avg 5µs/call:
# 67 times (313µs+0s) by Class::MOP::Method::wrap at line 46 of Class/MOP/Method.pm, avg 5µs/call | ||||
| 103 | 67 | 13µs | my $class = shift; | ||
| 104 | 67 | 9µs | return Class::MOP::Class->initialize($class)->new_object(@_) | ||
| 105 | if $class ne __PACKAGE__; | ||||
| 106 | |||||
| 107 | 67 | 17µs | my $params = @_ == 1 ? $_[0] : {@_}; | ||
| 108 | |||||
| 109 | 67 | 300µs | return bless { | ||
| 110 | # inherited from Class::MOP::Method | ||||
| 111 | 'body' => $params->{body}, | ||||
| 112 | 'associated_metaclass' => $params->{associated_metaclass}, | ||||
| 113 | 'package_name' => $params->{package_name}, | ||||
| 114 | 'name' => $params->{name}, | ||||
| 115 | 'original_method' => $params->{original_method}, | ||||
| 116 | |||||
| 117 | # defined in this class | ||||
| 118 | 'modifier_table' => $params->{modifier_table} | ||||
| 119 | } => $class; | ||||
| 120 | } | ||||
| 121 | |||||
| 122 | sub get_original_method { | ||||
| 123 | my $code = shift; | ||||
| 124 | $code->original_method; | ||||
| 125 | } | ||||
| 126 | |||||
| 127 | # spent 22µs (11+11) within Class::MOP::Method::Wrapped::add_before_modifier which was called 2 times, avg 11µs/call:
# 2 times (11µs+11µs) by Class::MOP::Class::add_before_method_modifier at line 1079 of Class/MOP/Class.pm, avg 11µs/call | ||||
| 128 | 2 | 400ns | my $code = shift; | ||
| 129 | 2 | 200ns | my $modifier = shift; | ||
| 130 | 2 | 2µs | unshift @{$code->{'modifier_table'}->{before}} => $modifier; | ||
| 131 | 2 | 6µs | 2 | 11µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 11µs making 2 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71], avg 5µs/call |
| 132 | } | ||||
| 133 | |||||
| 134 | sub before_modifiers { | ||||
| 135 | my $code = shift; | ||||
| 136 | return @{$code->{'modifier_table'}->{before}}; | ||||
| 137 | } | ||||
| 138 | |||||
| 139 | # spent 11µs (6+5) within Class::MOP::Method::Wrapped::add_after_modifier which was called:
# once (6µs+5µs) by Class::MOP::Class::add_after_method_modifier at line 1089 of Class/MOP/Class.pm | ||||
| 140 | 1 | 200ns | my $code = shift; | ||
| 141 | 1 | 200ns | my $modifier = shift; | ||
| 142 | 1 | 1µs | push @{$code->{'modifier_table'}->{after}} => $modifier; | ||
| 143 | 1 | 3µs | 1 | 5µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 5µs making 1 call to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71] |
| 144 | } | ||||
| 145 | |||||
| 146 | sub after_modifiers { | ||||
| 147 | my $code = shift; | ||||
| 148 | return @{$code->{'modifier_table'}->{after}}; | ||||
| 149 | } | ||||
| 150 | |||||
| 151 | { | ||||
| 152 | # NOTE: | ||||
| 153 | # this is another possible candidate for | ||||
| 154 | # optimization as well. There is an overhead | ||||
| 155 | # associated with the currying that, if | ||||
| 156 | # eliminated might make around modifiers | ||||
| 157 | # more manageable. | ||||
| 158 | 131 | 16µs | # spent 340µs within Class::MOP::Method::Wrapped::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:164] which was called 65 times, avg 5µs/call:
# 65 times (340µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 171, avg 5µs/call | ||
| 159 | 65 | 7µs | my $f1 = pop; | ||
| 160 | 130 | 154µs | return $f1 unless @_; | ||
| 161 | 65 | 7µs | my $f2 = pop; | ||
| 162 | 1044 | 10.3ms | 979 | 79.8ms | # spent 84.6ms (4.86+79.8) within Class::MOP::Method::Wrapped::__ANON__[/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:162] which was called 979 times, avg 86µs/call:
# 979 times (4.86ms+79.8ms) by Class::MOP::Class::Immutable::Class::MOP::Class::_method_map or Class::MOP::Class::Immutable::Class::MOP::Class::class_precedence_list or Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes or Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance or Class::MOP::Class::Immutable::Class::MOP::Class::is_immutable or Class::MOP::Class::Immutable::Class::MOP::Class::linearized_isa or Class::MOP::Class::Immutable::Class::MOP::Class::superclasses or Moose::Meta::Class::__ANON__::SERIAL::1::_canonicalize_handles or Moose::Meta::Class::__ANON__::SERIAL::1::_make_delegation_method or Moose::Meta::Class::__ANON__::SERIAL::2::_eval_environment or Moose::Meta::Class::__ANON__::SERIAL::2::_inline_tc_code or Moose::Meta::Class::__ANON__::SERIAL::2::new or Moose::Meta::Class::__ANON__::SERIAL::3::_eval_environment or Moose::Meta::Class::__ANON__::SERIAL::3::_inline_tc_code or Moose::Meta::Class::__ANON__::SERIAL::3::new or Moose::Meta::Class::__ANON__::SERIAL::4::new or Moose::Meta::Class::__ANON__::SERIAL::5::new or Moose::Meta::Class::__ANON__::SERIAL::6::_eval_environment or Moose::Meta::Class::__ANON__::SERIAL::6::_inline_tc_code or Moose::Meta::Class::__ANON__::SERIAL::6::new or Moose::Meta::Class::__ANON__::SERIAL::7::new or Moose::Meta::Class::__ANON__::SERIAL::8::_eval_environment or Moose::Meta::Class::__ANON__::SERIAL::8::_inline_tc_code or Moose::Meta::Class::__ANON__::SERIAL::8::new at line 91, avg 86µs/call # spent 80.4ms making 979 calls to Class::MOP::Class:::around, avg 82µs/call, recursion: max depth 3, sum of overlapping time 583µs |
| 163 | 65 | 14µs | redo; | ||
| 164 | 1 | 1µs | }}; | ||
| 165 | |||||
| 166 | # spent 949µs (457+492) within Class::MOP::Method::Wrapped::add_around_modifier which was called 65 times, avg 15µs/call:
# 65 times (457µs+492µs) by Class::MOP::Class::add_around_method_modifier at line 1099 of Class/MOP/Class.pm, avg 15µs/call | ||||
| 167 | 65 | 7µs | my $code = shift; | ||
| 168 | 65 | 1µs | my $modifier = shift; | ||
| 169 | 65 | 58µs | unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier; | ||
| 170 | $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->( | ||||
| 171 | 65 | 152µs | 65 | 340µs | @{$code->{'modifier_table'}->{around}->{methods}}, # spent 340µs making 65 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:164], avg 5µs/call |
| 172 | $code->{'modifier_table'}->{orig} | ||||
| 173 | ); | ||||
| 174 | 65 | 136µs | 65 | 152µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 152µs making 65 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71], avg 2µs/call |
| 175 | } | ||||
| 176 | } | ||||
| 177 | |||||
| 178 | sub around_modifiers { | ||||
| 179 | my $code = shift; | ||||
| 180 | return @{$code->{'modifier_table'}->{around}->{methods}}; | ||||
| 181 | } | ||||
| 182 | |||||
| 183 | sub _make_compatible_with { | ||||
| 184 | my $self = shift; | ||||
| 185 | my ($other) = @_; | ||||
| 186 | |||||
| 187 | # XXX: this is pretty gross. the issue here is that CMOP::Method::Wrapped | ||||
| 188 | # objects are subclasses of CMOP::Method, but when we get to moose, they'll | ||||
| 189 | # need to be compatible with Moose::Meta::Method, which isn't possible. the | ||||
| 190 | # right solution here is to make ::Wrapped into a role that gets applied to | ||||
| 191 | # whatever the method_metaclass happens to be and get rid of | ||||
| 192 | # wrapped_method_metaclass entirely, but that's not going to happen until | ||||
| 193 | # we ditch cmop and get roles into the bootstrapping, so. i'm not | ||||
| 194 | # maintaining the previous behavior of turning them into instances of the | ||||
| 195 | # new method_metaclass because that's equally broken, and at least this way | ||||
| 196 | # any issues will at least be detectable and potentially fixable. -doy | ||||
| 197 | return $self unless $other->_is_compatible_with($self->_real_ref_name); | ||||
| 198 | |||||
| 199 | return $self->SUPER::_make_compatible_with(@_); | ||||
| 200 | } | ||||
| 201 | |||||
| 202 | 1 | 3µs | 1; | ||
| 203 | |||||
| 204 | # ABSTRACT: Method Meta Object for methods with before/after/around modifiers | ||||
| 205 | |||||
| 206 | __END__ |