← Index
NYTProf Performance Profile   « line view »
For script/ponapi
  Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:10 2016

Filename/usr/local/lib/perl/5.18.2/Class/MOP/Method/Wrapped.pm
StatementsExecuted 3700559 statements in 23.6s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
66211.15ms2.63msClass::MOP::Method::Wrapped::::wrapClass::MOP::Method::Wrapped::wrap
6211481µs888µsClass::MOP::Method::Wrapped::::add_around_modifierClass::MOP::Method::Wrapped::add_around_modifier
13231348µs348µsClass::MOP::Method::Wrapped::::__ANON__[:65]Class::MOP::Method::Wrapped::__ANON__[:65]
6611289µs289µsClass::MOP::Method::Wrapped::::_newClass::MOP::Method::Wrapped::_new
6211280µs280µsClass::MOP::Method::Wrapped::::__ANON__[:166]Class::MOP::Method::Wrapped::__ANON__[:166]
11135µs46µsClass::MOP::Method::Wrapped::::BEGIN@4Class::MOP::Method::Wrapped::BEGIN@4
41123µs41µsClass::MOP::Method::Wrapped::::add_before_modifierClass::MOP::Method::Wrapped::add_before_modifier
11111µs28µsClass::MOP::Method::Wrapped::::BEGIN@10Class::MOP::Method::Wrapped::BEGIN@10
1116µs25µsClass::MOP::Method::Wrapped::::BEGIN@8Class::MOP::Method::Wrapped::BEGIN@8
1116µs10µsClass::MOP::Method::Wrapped::::BEGIN@5Class::MOP::Method::Wrapped::BEGIN@5
1116µs27µsClass::MOP::Method::Wrapped::::BEGIN@7Class::MOP::Method::Wrapped::BEGIN@7
0000s0sClass::MOP::Method::Wrapped::::__ANON__[:164]Class::MOP::Method::Wrapped::__ANON__[:164]
0000s0sClass::MOP::Method::Wrapped::::__ANON__[:39]Class::MOP::Method::Wrapped::__ANON__[:39]
0000s0sClass::MOP::Method::Wrapped::::__ANON__[:45]Class::MOP::Method::Wrapped::__ANON__[:45]
0000s0sClass::MOP::Method::Wrapped::::__ANON__[:60]Class::MOP::Method::Wrapped::__ANON__[:60]
0000s0sClass::MOP::Method::Wrapped::::__ANON__[:96]Class::MOP::Method::Wrapped::__ANON__[:96]
0000s0sClass::MOP::Method::Wrapped::::_make_compatible_withClass::MOP::Method::Wrapped::_make_compatible_with
0000s0sClass::MOP::Method::Wrapped::::add_after_modifierClass::MOP::Method::Wrapped::add_after_modifier
0000s0sClass::MOP::Method::Wrapped::::after_modifiersClass::MOP::Method::Wrapped::after_modifiers
0000s0sClass::MOP::Method::Wrapped::::around_modifiersClass::MOP::Method::Wrapped::around_modifiers
0000s0sClass::MOP::Method::Wrapped::::before_modifiersClass::MOP::Method::Wrapped::before_modifiers
0000s0sClass::MOP::Method::Wrapped::::get_original_methodClass::MOP::Method::Wrapped::get_original_method
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Class::MOP::Method::Wrapped;
21500nsour $VERSION = '2.1604';
3
4221µs256µs
# spent 46µs (35+10) within Class::MOP::Method::Wrapped::BEGIN@4 which was called: # once (35µs+10µs) by Class::MOP::Class::BEGIN@8 at line 4
use strict;
# spent 46µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@4 # spent 10µs making 1 call to strict::import
5220µs214µs
# spent 10µs (6+4) within Class::MOP::Method::Wrapped::BEGIN@5 which was called: # once (6µs+4µs) by Class::MOP::Class::BEGIN@8 at line 5
use warnings;
# spent 10µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@5 # spent 4µs making 1 call to warnings::import
6
7223µs248µs
# spent 27µs (6+21) within Class::MOP::Method::Wrapped::BEGIN@7 which was called: # once (6µs+21µs) by Class::MOP::Class::BEGIN@8 at line 7
use Scalar::Util 'blessed';
# spent 27µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@7 # spent 21µs making 1 call to Exporter::import
8220µs243µs
# spent 25µs (6+18) within Class::MOP::Method::Wrapped::BEGIN@8 which was called: # once (6µs+18µs) by Class::MOP::Class::BEGIN@8 at line 8
use Sub::Name 'subname';
# spent 25µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@8 # spent 18µs making 1 call to Exporter::import
9
102778µs245µs
# spent 28µs (11+17) within Class::MOP::Method::Wrapped::BEGIN@10 which was called: # once (11µs+17µs) by Class::MOP::Class::BEGIN@8 at line 10
use parent 'Class::MOP::Method';
# spent 28µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@10 # spent 17µs making 1 call to parent::import
11
12# NOTE:
13# this ugly beast is the result of trying
14# to micro optimize this as much as possible
15# while not completely loosing maintainability.
16# At this point it's "fast enough", after all
17# you can't get something for nothing :)
18
# spent 348µs within Class::MOP::Method::Wrapped::__ANON__[/usr/local/lib/perl/5.18.2/Class/MOP/Method/Wrapped.pm:65] which was called 132 times, avg 3µs/call: # 66 times (203µs+0s) by Class::MOP::Method::Wrapped::wrap at line 86, avg 3µs/call # 62 times (126µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 176, avg 2µs/call # 4 times (18µs+0s) by Class::MOP::Method::Wrapped::add_before_modifier at line 133, avg 5µs/call
my $_build_wrapped_method = sub {
1913222µs my $modifier_table = shift;
2013285µs my ($before, $after, $around) = (
21 $modifier_table->{before},
22 $modifier_table->{after},
23 $modifier_table->{around},
24 );
25132304µs if (@$before && @$after) {
26 $modifier_table->{cache} = sub {
27 for my $c (@$before) { $c->(@_) };
28 my @rval;
29 ((defined wantarray) ?
30 ((wantarray) ?
31 (@rval = $around->{cache}->(@_))
32 :
33 ($rval[0] = $around->{cache}->(@_)))
34 :
35 $around->{cache}->(@_));
36 for my $c (@$after) { $c->(@_) };
37 return unless defined wantarray;
38 return wantarray ? @rval : $rval[0];
39 }
40 }
41 elsif (@$before && !@$after) {
42 $modifier_table->{cache} = sub {
43128192µs64219ms for my $c (@$before) { $c->(@_) };
# spent 219ms making 64 calls to Class::MOP::Class:::before, avg 3.42ms/call
4464252µs64139ms return $around->{cache}->(@_);
# spent 137ms making 32 calls to Moose::Meta::Attribute::install_accessors, avg 4.28ms/call # spent 2.56ms making 32 calls to Moose::Meta::Attribute::_process_options, avg 80µs/call
45 }
46410µs }
47 elsif (@$after && !@$before) {
48 $modifier_table->{cache} = sub {
49 my @rval;
50 ((defined wantarray) ?
51 ((wantarray) ?
52 (@rval = $around->{cache}->(@_))
53 :
54 ($rval[0] = $around->{cache}->(@_)))
55 :
56 $around->{cache}->(@_));
57 for my $c (@$after) { $c->(@_) };
58 return unless defined wantarray;
59 return wantarray ? @rval : $rval[0];
60 }
61 }
62 else {
6312846µs $modifier_table->{cache} = $around->{cache};
64 }
6512µs};
66
67
# spent 2.63ms (1.15+1.48) within Class::MOP::Method::Wrapped::wrap which was called 66 times, avg 40µs/call: # 61 times (1.06ms+1.38ms) by Class::MOP::Class::__ANON__[/usr/local/lib/perl/5.18.2/Class/MOP/Class.pm:1082] at line 1068 of Class/MOP/Class.pm, avg 40µs/call # 5 times (88µs+103µs) by Class::MOP::Class::__ANON__[/usr/local/lib/perl/5.18.2/Class/MOP/Class.pm:1082] at line 1075 of Class/MOP/Class.pm, avg 38µs/call
sub wrap {
686673µs my ( $class, $code, %params ) = @_;
69
7066265µs13270µs (blessed($code) && $code->isa('Class::MOP::Method'))
# spent 38µs making 66 calls to Scalar::Util::blessed, avg 570ns/call # spent 32µs making 66 calls to UNIVERSAL::isa, avg 491ns/call
71 || $class->_throw_exception( CanOnlyWrapBlessedCode => params => \%params,
72 class => $class,
73 code => $code
74 );
75
7666390µs13244µs my $modifier_table = {
# spent 44µs making 132 calls to Class::MOP::Method::body, avg 331ns/call
77 cache => undef,
78 orig => $code->body,
79 before => [],
80 after => [],
81 around => {
82 cache => $code->body,
83 methods => [],
84 },
85 };
866665µs66203µs $_build_wrapped_method->($modifier_table);
# spent 203µs making 66 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 3µs/call
87
88 # get these from the original unless explicitly overridden
896635µs my $pkg_name = $params{package_name} || $code->package_name;
906619µs my $method_name = $params{name} || $code->name;
91
92 return $class->SUPER::wrap(
93 sub {
9412327809.57s12327804.35s my $wrapped = subname "${pkg_name}::_wrapped_${method_name}" => $modifier_table->{cache};
# spent 4.35s making 1232780 calls to Sub::Name::subname, avg 4µs/call
9512327806.66s123278015.2s return $wrapped->(@_) ;
# spent 14.7s making 1230932 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_does_role, avg 12µs/call # spent 218ms making 21 calls to Moose::Meta::Class::__ANON__::SERIAL::1::_wrapped_install_accessors, avg 10.4ms/call # spent 117ms making 11 calls to Moose::Meta::Class::__ANON__::SERIAL::7::_wrapped_install_accessors, avg 10.6ms/call # spent 45.4ms making 33 calls to Moose::Meta::Class::__ANON__::SERIAL::1::_wrapped__make_delegation_method, avg 1.38ms/call # spent 23.7ms making 21 calls to Moose::Meta::Class::__ANON__::SERIAL::2::_wrapped_new, avg 1.13ms/call # spent 23.5ms making 17 calls to Moose::Meta::Class::__ANON__::SERIAL::7::_wrapped__make_delegation_method, avg 1.38ms/call # spent 14.8ms making 11 calls to Moose::Meta::Class::__ANON__::SERIAL::7::_wrapped__process_options, avg 1.35ms/call # spent 9.46ms making 11 calls to Moose::Meta::Class::__ANON__::SERIAL::8::_wrapped_new, avg 860µs/call # spent 9.15ms making 21 calls to Moose::Meta::Class::__ANON__::SERIAL::1::_wrapped__process_options, avg 436µs/call # spent 7.34ms making 515 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance, avg 14µs/call # spent 7.23ms making 4 calls to Moose::Meta::Class::__ANON__::SERIAL::10::_wrapped_new, avg 1.81ms/call # spent 5.57ms making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::6::_wrapped_new, avg 1.86ms/call # spent 3.89ms making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::3::_wrapped_new, avg 1.30ms/call # spent 3.70ms making 2 calls to Moose::Meta::Class::__ANON__::SERIAL::9::_wrapped_new, avg 1.85ms/call # spent 3.59ms making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::4::_wrapped_new, avg 1.20ms/call # spent 3.46ms making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::5::_wrapped_new, avg 1.15ms/call # spent 2.59ms making 293 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes, avg 9µs/call # spent 1.11ms making 300 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map, avg 4µs/call # spent 1.08ms making 4 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_calculate_all_roles_with_inheritance, avg 271µs/call # spent 913µs making 4 calls to Moose::Meta::Class::__ANON__::SERIAL::10::_wrapped__inline_tc_code, avg 228µs/call # spent 884µs making 4 calls to Moose::Meta::Class::__ANON__::SERIAL::10::_wrapped__eval_environment, avg 221µs/call # spent 779µs making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::6::_wrapped__eval_environment, avg 260µs/call # spent 773µs making 42 calls to Moose::Meta::Class::__ANON__::SERIAL::1::_wrapped__canonicalize_handles, avg 18µs/call # spent 1.49ms making 33 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_class_precedence_list, avg 45µs/call, recursion: max depth 3, sum of overlapping time 743µs # spent 597µs making 95 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa, avg 6µs/call # spent 562µs making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::6::_wrapped__inline_tc_code, avg 187µs/call # spent 481µs making 103 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped__method_map, avg 5µs/call # spent 406µs making 22 calls to Moose::Meta::Class::__ANON__::SERIAL::7::_wrapped__canonicalize_handles, avg 18µs/call # spent 397µs making 114 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_get_meta_instance, avg 3µs/call # spent 394µs making 4 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_calculate_all_roles, avg 99µs/call # spent 304µs making 32 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_linearized_isa, avg 9µs/call # spent 192µs making 59 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable, avg 3µs/call # spent 190µs making 10 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_class_precedence_list, avg 19µs/call # spent 182µs making 12 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_superclasses, avg 15µs/call # spent 127µs making 3 calls to Moose::Meta::Class::__ANON__::SERIAL::6::_wrapped__inline_check_argument_count, avg 42µs/call # spent 96µs making 28 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_is_immutable, avg 3µs/call # spent 42µs making 1 call to Class::MOP::Class::Immutable::Moose::Meta::Class::_wrapped_superclasses
96 },
9766366µs661.17ms package_name => $pkg_name,
# spent 1.17ms making 66 calls to Class::MOP::Method::wrap, avg 18µs/call
98 name => $method_name,
99 original_method => $code,
100 modifier_table => $modifier_table,
101 );
102}
103
104
# spent 289µs within Class::MOP::Method::Wrapped::_new which was called 66 times, avg 4µs/call: # 66 times (289µs+0s) by Class::MOP::Method::wrap at line 49 of Class/MOP/Method.pm, avg 4µs/call
sub _new {
1056618µs my $class = shift;
1066619µs return Class::MOP::Class->initialize($class)->new_object(@_)
107 if $class ne __PACKAGE__;
108
1096626µs my $params = @_ == 1 ? $_[0] : {@_};
110
11166280µs return bless {
112 # inherited from Class::MOP::Method
113 'body' => $params->{body},
114 'associated_metaclass' => $params->{associated_metaclass},
115 'package_name' => $params->{package_name},
116 'name' => $params->{name},
117 'original_method' => $params->{original_method},
118
119 # defined in this class
120 'modifier_table' => $params->{modifier_table}
121 } => $class;
122}
123
124sub get_original_method {
125 my $code = shift;
126 $code->original_method;
127}
128
129
# spent 41µs (23+18) within Class::MOP::Method::Wrapped::add_before_modifier which was called 4 times, avg 10µs/call: # 4 times (23µs+18µs) by Class::MOP::Class::add_before_method_modifier at line 1089 of Class/MOP/Class.pm, avg 10µs/call
sub add_before_modifier {
13041µs my $code = shift;
1314800ns my $modifier = shift;
13245µs unshift @{$code->{'modifier_table'}->{before}} => $modifier;
133411µs418µs $_build_wrapped_method->($code->{'modifier_table'});
# spent 18µs making 4 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 5µs/call
134}
135
136sub before_modifiers {
137 my $code = shift;
138 return @{$code->{'modifier_table'}->{before}};
139}
140
141sub add_after_modifier {
142 my $code = shift;
143 my $modifier = shift;
144 push @{$code->{'modifier_table'}->{after}} => $modifier;
145 $_build_wrapped_method->($code->{'modifier_table'});
146}
147
148sub after_modifiers {
149 my $code = shift;
150 return @{$code->{'modifier_table'}->{after}};
151}
152
153{
154 # NOTE:
155 # this is another possible candidate for
156 # optimization as well. There is an overhead
157 # associated with the currying that, if
158 # eliminated might make around modifiers
159 # more manageable.
16012523µs
# spent 280µs within Class::MOP::Method::Wrapped::__ANON__[/usr/local/lib/perl/5.18.2/Class/MOP/Method/Wrapped.pm:166] which was called 62 times, avg 5µs/call: # 62 times (280µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 173, avg 5µs/call
my $compile_around_method = sub {{
1616210µs my $f1 = pop;
162124157µs return $f1 unless @_;
1636210µs my $f2 = pop;
16412327787.41s12327169.44s push @_, sub { $f2->( $f1, @_ ) };
# spent 9.44s making 1232716 calls to Class::MOP::Class:::around, avg 8µs/call, recursion: max depth 3, sum of overlapping time 710µs
1656218µs redo;
16613µs }};
167
168
# spent 888µs (481+407) within Class::MOP::Method::Wrapped::add_around_modifier which was called 62 times, avg 14µs/call: # 62 times (481µs+407µs) by Class::MOP::Class::add_around_method_modifier at line 1109 of Class/MOP/Class.pm, avg 14µs/call
sub add_around_modifier {
1696212µs my $code = shift;
170629µs my $modifier = shift;
1716278µs unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier;
172 $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->(
17362131µs62280µs @{$code->{'modifier_table'}->{around}->{methods}},
# spent 280µs making 62 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:166], avg 5µs/call
174 $code->{'modifier_table'}->{orig}
175 );
17662152µs62126µs $_build_wrapped_method->($code->{'modifier_table'});
# spent 126µs making 62 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 2µs/call
177 }
178}
179
180sub around_modifiers {
181 my $code = shift;
182 return @{$code->{'modifier_table'}->{around}->{methods}};
183}
184
185sub _make_compatible_with {
186 my $self = shift;
187 my ($other) = @_;
188
189 # XXX: this is pretty gross. the issue here is that CMOP::Method::Wrapped
190 # objects are subclasses of CMOP::Method, but when we get to moose, they'll
191 # need to be compatible with Moose::Meta::Method, which isn't possible. the
192 # right solution here is to make ::Wrapped into a role that gets applied to
193 # whatever the method_metaclass happens to be and get rid of
194 # wrapped_method_metaclass entirely, but that's not going to happen until
195 # we ditch cmop and get roles into the bootstrapping, so. i'm not
196 # maintaining the previous behavior of turning them into instances of the
197 # new method_metaclass because that's equally broken, and at least this way
198 # any issues will at least be detectable and potentially fixable. -doy
199 return $self unless $other->_is_compatible_with($self->_real_ref_name);
200
201 return $self->SUPER::_make_compatible_with(@_);
202}
203
20413µs1;
205
206# ABSTRACT: Method Meta Object for methods with before/after/around modifiers
207
208__END__