← Index
NYTProf Performance Profile   « line view »
For /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
  Run on Mon Jan 29 16:55:34 2018
Reported on Mon Jan 29 16:57:06 2018

Filename/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm
StatementsExecuted 3410 statements in 16.6ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
43117.16ms7.39msClass::MOP::Method::Wrapped::::add_around_modifier Class::MOP::Method::Wrapped::add_around_modifier
296114.52ms5.80msClass::MOP::Class::Immutable::Class::MOP::Class::::_wrapped_get_meta_instanceClass::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance
4311554µs1.22msClass::MOP::Method::Wrapped::::wrap Class::MOP::Method::Wrapped::wrap
24611320µs599µsClass::MOP::Class::Immutable::Class::MOP::Class::::_wrapped__method_mapClass::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map
8621158µs158µsClass::MOP::Method::Wrapped::::__ANON__[:65] Class::MOP::Method::Wrapped::__ANON__[:65]
4311153µs153µsClass::MOP::Method::Wrapped::::__ANON__[:166] Class::MOP::Method::Wrapped::__ANON__[:166]
4311136µs136µsClass::MOP::Method::Wrapped::::_new Class::MOP::Method::Wrapped::_new
6711104µs291µsClass::MOP::Class::Immutable::Class::MOP::Class::::_wrapped_linearized_isaClass::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa
411164µs822µsClass::MOP::Class::Immutable::Class::MOP::Class::::_wrapped_get_all_attributesClass::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes
231141µs55µsClass::MOP::Class::Immutable::Class::MOP::Class::::_wrapped_is_immutableClass::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable
1119µs10µsClass::MOP::Method::Wrapped::::BEGIN@4 Class::MOP::Method::Wrapped::BEGIN@4
1115µs17µsClass::MOP::Method::Wrapped::::BEGIN@8 Class::MOP::Method::Wrapped::BEGIN@8
1114µs18µsClass::MOP::Method::Wrapped::::BEGIN@10 Class::MOP::Method::Wrapped::BEGIN@10
1114µs23µsClass::MOP::Method::Wrapped::::BEGIN@7 Class::MOP::Method::Wrapped::BEGIN@7
1114µs7µsClass::MOP::Method::Wrapped::::BEGIN@5 Class::MOP::Method::Wrapped::BEGIN@5
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_with Class::MOP::Method::Wrapped::_make_compatible_with
0000s0sClass::MOP::Method::Wrapped::::add_after_modifier Class::MOP::Method::Wrapped::add_after_modifier
0000s0sClass::MOP::Method::Wrapped::::add_before_modifier Class::MOP::Method::Wrapped::add_before_modifier
0000s0sClass::MOP::Method::Wrapped::::after_modifiers Class::MOP::Method::Wrapped::after_modifiers
0000s0sClass::MOP::Method::Wrapped::::around_modifiers Class::MOP::Method::Wrapped::around_modifiers
0000s0sClass::MOP::Method::Wrapped::::before_modifiers Class::MOP::Method::Wrapped::before_modifiers
0000s0sClass::MOP::Method::Wrapped::::get_original_method Class::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;
21300nsour $VERSION = '2.1605';
3
4214µs212µs
# spent 10µs (9+1) within Class::MOP::Method::Wrapped::BEGIN@4 which was called: # once (9µs+1µs) by Class::MOP::Class::BEGIN@8 at line 4
use strict;
# spent 10µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@4 # spent 2µs making 1 call to strict::import
5213µs29µs
# spent 7µs (4+3) within Class::MOP::Method::Wrapped::BEGIN@5 which was called: # once (4µs+3µs) by Class::MOP::Class::BEGIN@8 at line 5
use warnings;
# spent 7µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@5 # spent 3µs making 1 call to warnings::import
6
7215µs242µs
# spent 23µs (4+19) within Class::MOP::Method::Wrapped::BEGIN@7 which was called: # once (4µs+19µs) by Class::MOP::Class::BEGIN@8 at line 7
use Scalar::Util 'blessed';
# spent 23µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@7 # spent 19µs making 1 call to Exporter::import
8215µs230µs
# spent 17µs (5+13) within Class::MOP::Method::Wrapped::BEGIN@8 which was called: # once (5µs+13µs) by Class::MOP::Class::BEGIN@8 at line 8
use Sub::Name 'subname';
# spent 17µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@8 # spent 12µs making 1 call to Exporter::import
9
102534µs232µs
# spent 18µs (4+14) within Class::MOP::Method::Wrapped::BEGIN@10 which was called: # once (4µs+14µs) by Class::MOP::Class::BEGIN@8 at line 10
use parent 'Class::MOP::Method';
# spent 18µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@10 # spent 14µ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 158µs within Class::MOP::Method::Wrapped::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm:65] which was called 86 times, avg 2µs/call: # 43 times (84µs+0s) by Class::MOP::Method::Wrapped::wrap at line 86, avg 2µs/call # 43 times (73µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 176, avg 2µs/call
my $_build_wrapped_method = sub {
198611µs my $modifier_table = shift;
20 my ($before, $after, $around) = (
21 $modifier_table->{before},
22 $modifier_table->{after},
23 $modifier_table->{around},
248637µs );
2586162µ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 {
43 for my $c (@$before) { $c->(@_) };
44 return $around->{cache}->(@_);
45 }
46 }
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 {
638623µs $modifier_table->{cache} = $around->{cache};
64 }
6512µs};
66
67
# spent 1.22ms (554µs+663µs) within Class::MOP::Method::Wrapped::wrap which was called 43 times, avg 28µs/call: # 43 times (554µs+663µs) by Class::MOP::Class::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Class.pm:1082] at line 1068 of Class/MOP/Class.pm, avg 28µs/call
sub wrap {
684335µs my ( $class, $code, %params ) = @_;
69
7043117µs8624µs (blessed($code) && $code->isa('Class::MOP::Method'))
# spent 13µs making 43 calls to Scalar::Util::blessed, avg 307ns/call # spent 10µs making 43 calls to UNIVERSAL::isa, avg 244ns/call
71 || $class->_throw_exception( CanOnlyWrapBlessedCode => params => \%params,
72 class => $class,
73 code => $code
74 );
75
7643187µs8618µs my $modifier_table = {
# spent 18µs making 86 calls to Class::MOP::Method::body, avg 208ns/call
77 cache => undef,
78 orig => $code->body,
79 before => [],
80 after => [],
81 around => {
82 cache => $code->body,
83 methods => [],
84 },
85 };
864331µs4384µs $_build_wrapped_method->($modifier_table);
# spent 84µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 2µs/call
87
88 # get these from the original unless explicitly overridden
894315µs my $pkg_name = $params{package_name} || $code->package_name;
904310µs my $method_name = $params{name} || $code->name;
91
92 return $class->SUPER::wrap(
93 sub {
946732.56ms6731.66ms my $wrapped = subname "${pkg_name}::_wrapped_${method_name}" => $modifier_table->{cache};
# spent 1.66ms making 673 calls to Sub::Name::subname, avg 2µs/call
956731.00ms6737.57ms return $wrapped->(@_) ;
# spent 5.80ms making 296 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance, avg 20µs/call # spent 822µs making 41 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes, avg 20µs/call # spent 599µs making 246 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map, avg 2µs/call # spent 291µs making 67 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa, avg 4µs/call # spent 55µs making 23 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable, avg 2µs/call
96 },
9743183µs43537µs package_name => $pkg_name,
# spent 537µs making 43 calls to Class::MOP::Method::wrap, avg 12µs/call
98 name => $method_name,
99 original_method => $code,
100 modifier_table => $modifier_table,
101 );
102}
103
104
# spent 136µs within Class::MOP::Method::Wrapped::_new which was called 43 times, avg 3µs/call: # 43 times (136µs+0s) by Class::MOP::Method::wrap at line 49 of Class/MOP/Method.pm, avg 3µs/call
sub _new {
105438µs my $class = shift;
1064310µs return Class::MOP::Class->initialize($class)->new_object(@_)
107 if $class ne __PACKAGE__;
108
1094312µs my $params = @_ == 1 ? $_[0] : {@_};
110
111 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}
12143128µs } => $class;
122}
123
124sub get_original_method {
125 my $code = shift;
126 $code->original_method;
127}
128
129sub add_before_modifier {
130 my $code = shift;
131 my $modifier = shift;
132 unshift @{$code->{'modifier_table'}->{before}} => $modifier;
133 $_build_wrapped_method->($code->{'modifier_table'});
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.
160
# spent 153µs within Class::MOP::Method::Wrapped::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm:166] which was called 43 times, avg 4µs/call: # 43 times (153µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 175, avg 4µs/call
my $compile_around_method = sub {{
16112922µs my $f1 = pop;
162866.99ms return $f1 unless @_;
163437µs my $f2 = pop;
1647164.23ms6732.52ms
# spent 5.80ms (4.52+1.28) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance which was called 296 times, avg 20µs/call: # 296 times (4.52ms+1.28ms) by Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance at line 95, avg 20µs/call # spent 55µs (41+14) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable which was called 23 times, avg 2µs/call: # 23 times (41µs+14µs) by Class::MOP::Class::Immutable::Class::MOP::Class::is_immutable at line 95, avg 2µs/call # spent 822µs (64+758) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes which was called 41 times, avg 20µs/call: # 41 times (64µs+758µs) by Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes at line 95, avg 20µs/call # spent 291µs (104+188) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa which was called 67 times, avg 4µs/call: # 67 times (104µs+188µs) by Class::MOP::Class::Immutable::Class::MOP::Class::linearized_isa at line 95, avg 4µs/call # spent 599µs (320+279) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map which was called 246 times, avg 2µs/call: # 246 times (320µs+279µs) by Class::MOP::Class::Immutable::Class::MOP::Class::_method_map at line 95, avg 2µs/call
push @_, sub { $f2->( $f1, @_ ) };
# spent 2.52ms making 673 calls to Class::MOP::Class:::around, avg 4µs/call
1654310µs redo;
16611µs }};
167
168
# spent 7.39ms (7.16+226µs) within Class::MOP::Method::Wrapped::add_around_modifier which was called 43 times, avg 172µs/call: # 43 times (7.16ms+226µs) by Class::MOP::Class::add_around_method_modifier at line 1109 of Class/MOP/Class.pm, avg 172µs/call
sub add_around_modifier {
169436µs my $code = shift;
170435µs my $modifier = shift;
1714335µs unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier;
172 $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->(
173 @{$code->{'modifier_table'}->{around}->{methods}},
174 $code->{'modifier_table'}->{orig}
1754385µs43153µs );
# spent 153µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:166], avg 4µs/call
1764379µs4373µs $_build_wrapped_method->($code->{'modifier_table'});
# spent 73µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 2µs/call
177 }
178}
179
1801200nssub 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__