Filename | /Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Method/Wrapped.pm |
Statements | Executed 3938 statements in 12.5ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1307 | 1 | 1 | 4.34ms | 12.2ms | __ANON__[:158] | Class::MOP::Method::Wrapped::
44 | 2 | 1 | 1.31ms | 3.26ms | wrap | Class::MOP::Method::Wrapped::
44 | 1 | 1 | 697µs | 697µs | _new | Class::MOP::Method::Wrapped::
43 | 1 | 1 | 460µs | 913µs | add_around_modifier | Class::MOP::Method::Wrapped::
88 | 3 | 1 | 349µs | 349µs | __ANON__[:64] | Class::MOP::Method::Wrapped::
43 | 1 | 1 | 309µs | 309µs | __ANON__[:160] | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 22µs | 45µs | BEGIN@4 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 14µs | 64µs | BEGIN@7 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 14µs | 20µs | BEGIN@5 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 13µs | 55µs | BEGIN@9 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 7µs | 14µs | add_before_modifier | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:38] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:44] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:59] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:87] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | _make_compatible_with | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | add_after_modifier | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | after_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | around_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | before_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | get_original_method | Class::MOP::Method::Wrapped::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Class::MOP::Method::Wrapped; | ||||
2 | 1 | 2µs | our $VERSION = '2.1403'; | ||
3 | |||||
4 | 2 | 40µs | 2 | 69µs | # spent 45µs (22+23) within Class::MOP::Method::Wrapped::BEGIN@4 which was called:
# once (22µs+23µs) by Class::MOP::Class::BEGIN@8 at line 4 # spent 45µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@4
# spent 23µs making 1 call to strict::import |
5 | 2 | 41µs | 2 | 27µs | # spent 20µs (14+7) within Class::MOP::Method::Wrapped::BEGIN@5 which was called:
# once (14µs+7µs) by Class::MOP::Class::BEGIN@8 at line 5 # spent 20µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@5
# spent 7µs making 1 call to warnings::import |
6 | |||||
7 | 2 | 47µs | 2 | 115µs | # spent 64µs (14+51) within Class::MOP::Method::Wrapped::BEGIN@7 which was called:
# once (14µs+51µs) by Class::MOP::Class::BEGIN@8 at line 7 # spent 64µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@7
# spent 51µs making 1 call to Exporter::import |
8 | |||||
9 | 2 | 1.43ms | 2 | 97µs | # spent 55µs (13+42) within Class::MOP::Method::Wrapped::BEGIN@9 which was called:
# once (13µs+42µs) by Class::MOP::Class::BEGIN@8 at line 9 # spent 55µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@9
# spent 42µs making 1 call to parent::import |
10 | |||||
11 | # NOTE: | ||||
12 | # this ugly beast is the result of trying | ||||
13 | # to micro optimize this as much as possible | ||||
14 | # while not completely loosing maintainability. | ||||
15 | # At this point it's "fast enough", after all | ||||
16 | # you can't get something for nothing :) | ||||
17 | # spent 349µs within Class::MOP::Method::Wrapped::__ANON__[/Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Method/Wrapped.pm:64] which was called 88 times, avg 4µs/call:
# 44 times (197µs+0s) by Class::MOP::Method::Wrapped::wrap at line 85, avg 4µs/call
# 43 times (144µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 170, avg 3µs/call
# once (7µs+0s) by Class::MOP::Method::Wrapped::add_before_modifier at line 127 | ||||
18 | 352 | 403µs | my $modifier_table = shift; | ||
19 | my ($before, $after, $around) = ( | ||||
20 | $modifier_table->{before}, | ||||
21 | $modifier_table->{after}, | ||||
22 | $modifier_table->{around}, | ||||
23 | ); | ||||
24 | if (@$before && @$after) { | ||||
25 | $modifier_table->{cache} = sub { | ||||
26 | for my $c (@$before) { $c->(@_) }; | ||||
27 | my @rval; | ||||
28 | ((defined wantarray) ? | ||||
29 | ((wantarray) ? | ||||
30 | (@rval = $around->{cache}->(@_)) | ||||
31 | : | ||||
32 | ($rval[0] = $around->{cache}->(@_))) | ||||
33 | : | ||||
34 | $around->{cache}->(@_)); | ||||
35 | for my $c (@$after) { $c->(@_) }; | ||||
36 | return unless defined wantarray; | ||||
37 | return wantarray ? @rval : $rval[0]; | ||||
38 | } | ||||
39 | } | ||||
40 | elsif (@$before && !@$after) { | ||||
41 | $modifier_table->{cache} = sub { | ||||
42 | for my $c (@$before) { $c->(@_) }; | ||||
43 | return $around->{cache}->(@_); | ||||
44 | } | ||||
45 | } | ||||
46 | elsif (@$after && !@$before) { | ||||
47 | $modifier_table->{cache} = sub { | ||||
48 | my @rval; | ||||
49 | ((defined wantarray) ? | ||||
50 | ((wantarray) ? | ||||
51 | (@rval = $around->{cache}->(@_)) | ||||
52 | : | ||||
53 | ($rval[0] = $around->{cache}->(@_))) | ||||
54 | : | ||||
55 | $around->{cache}->(@_)); | ||||
56 | for my $c (@$after) { $c->(@_) }; | ||||
57 | return unless defined wantarray; | ||||
58 | return wantarray ? @rval : $rval[0]; | ||||
59 | } | ||||
60 | } | ||||
61 | else { | ||||
62 | $modifier_table->{cache} = $around->{cache}; | ||||
63 | } | ||||
64 | 1 | 4µs | }; | ||
65 | |||||
66 | # spent 3.26ms (1.31+1.95) within Class::MOP::Method::Wrapped::wrap which was called 44 times, avg 74µs/call:
# 43 times (1.28ms+1.85ms) by Class::MOP::Class::__ANON__[/Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Class.pm:1082] at line 1068 of Class/MOP/Class.pm, avg 73µs/call
# once (30µs+98µs) by Class::MOP::Class::__ANON__[/Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Class.pm:1082] at line 1075 of Class/MOP/Class.pm | ||||
67 | 220 | 1.36ms | my ( $class, $code, %params ) = @_; | ||
68 | |||||
69 | 88 | 70µs | (blessed($code) && $code->isa('Class::MOP::Method')) # spent 38µs making 44 calls to Scalar::Util::blessed, avg 864ns/call
# spent 32µs making 44 calls to UNIVERSAL::isa, avg 730ns/call | ||
70 | || $class->_throw_exception( CanOnlyWrapBlessedCode => params => \%params, | ||||
71 | class => $class, | ||||
72 | code => $code | ||||
73 | ); | ||||
74 | |||||
75 | 88 | 49µs | my $modifier_table = { # spent 49µs making 88 calls to Class::MOP::Method::body, avg 557ns/call | ||
76 | cache => undef, | ||||
77 | orig => $code->body, | ||||
78 | before => [], | ||||
79 | after => [], | ||||
80 | around => { | ||||
81 | cache => $code->body, | ||||
82 | methods => [], | ||||
83 | }, | ||||
84 | }; | ||||
85 | 44 | 197µs | $_build_wrapped_method->($modifier_table); # spent 197µs making 44 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:64], avg 4µs/call | ||
86 | return $class->SUPER::wrap( | ||||
87 | 1307 | 4.00ms | 1307 | 12.2ms | sub { $modifier_table->{cache}->(@_) }, # spent 12.2ms making 1307 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:158], avg 9µs/call |
88 | # get these from the original | ||||
89 | # unless explicitly overridden | ||||
90 | 44 | 1.64ms | package_name => $params{package_name} || $code->package_name, # spent 1.64ms making 44 calls to Class::MOP::Method::wrap, avg 37µs/call | ||
91 | name => $params{name} || $code->name, | ||||
92 | original_method => $code, | ||||
93 | |||||
94 | modifier_table => $modifier_table, | ||||
95 | ); | ||||
96 | } | ||||
97 | |||||
98 | # spent 697µs within Class::MOP::Method::Wrapped::_new which was called 44 times, avg 16µs/call:
# 44 times (697µs+0s) by Class::MOP::Method::wrap at line 45 of Class/MOP/Method.pm, avg 16µs/call | ||||
99 | 176 | 730µs | my $class = shift; | ||
100 | return Class::MOP::Class->initialize($class)->new_object(@_) | ||||
101 | if $class ne __PACKAGE__; | ||||
102 | |||||
103 | my $params = @_ == 1 ? $_[0] : {@_}; | ||||
104 | |||||
105 | return bless { | ||||
106 | # inherited from Class::MOP::Method | ||||
107 | 'body' => $params->{body}, | ||||
108 | 'associated_metaclass' => $params->{associated_metaclass}, | ||||
109 | 'package_name' => $params->{package_name}, | ||||
110 | 'name' => $params->{name}, | ||||
111 | 'original_method' => $params->{original_method}, | ||||
112 | |||||
113 | # defined in this class | ||||
114 | 'modifier_table' => $params->{modifier_table} | ||||
115 | } => $class; | ||||
116 | } | ||||
117 | |||||
118 | sub get_original_method { | ||||
119 | my $code = shift; | ||||
120 | $code->original_method; | ||||
121 | } | ||||
122 | |||||
123 | # spent 14µs (7+7) within Class::MOP::Method::Wrapped::add_before_modifier which was called:
# once (7µs+7µs) by Class::MOP::Class::add_before_method_modifier at line 1089 of Class/MOP/Class.pm | ||||
124 | 4 | 6µs | my $code = shift; | ||
125 | my $modifier = shift; | ||||
126 | unshift @{$code->{'modifier_table'}->{before}} => $modifier; | ||||
127 | 1 | 7µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 7µs making 1 call to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:64] | ||
128 | } | ||||
129 | |||||
130 | sub before_modifiers { | ||||
131 | my $code = shift; | ||||
132 | return @{$code->{'modifier_table'}->{before}}; | ||||
133 | } | ||||
134 | |||||
135 | sub add_after_modifier { | ||||
136 | my $code = shift; | ||||
137 | my $modifier = shift; | ||||
138 | push @{$code->{'modifier_table'}->{after}} => $modifier; | ||||
139 | $_build_wrapped_method->($code->{'modifier_table'}); | ||||
140 | } | ||||
141 | |||||
142 | sub after_modifiers { | ||||
143 | my $code = shift; | ||||
144 | return @{$code->{'modifier_table'}->{after}}; | ||||
145 | } | ||||
146 | |||||
147 | { | ||||
148 | # NOTE: | ||||
149 | # this is another possible candidate for | ||||
150 | # optimization as well. There is an overhead | ||||
151 | # associated with the currying that, if | ||||
152 | # eliminated might make around modifiers | ||||
153 | # more manageable. | ||||
154 | 1 | 500ns | # spent 309µs within Class::MOP::Method::Wrapped::__ANON__[/Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Method/Wrapped.pm:160] which was called 43 times, avg 7µs/call:
# 43 times (309µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 167, avg 7µs/call | ||
155 | 344 | 336µs | my $f1 = pop; | ||
156 | return $f1 unless @_; | ||||
157 | my $f2 = pop; | ||||
158 | 1307 | 3.73ms | 1307 | 7.82ms | # spent 12.2ms (4.34+7.82) within Class::MOP::Method::Wrapped::__ANON__[/Users/ap13/perl5/lib/perl5/darwin-2level/Class/MOP/Method/Wrapped.pm:158] which was called 1307 times, avg 9µs/call:
# 1307 times (4.34ms+7.82ms) by Class::MOP::Class::Immutable::Class::MOP::Class::_method_map 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 at line 87, avg 9µs/call # spent 7.82ms making 1307 calls to Class::MOP::Class:::around, avg 6µs/call |
159 | redo; | ||||
160 | 1 | 2µs | }}; | ||
161 | |||||
162 | # spent 913µs (460+453) within Class::MOP::Method::Wrapped::add_around_modifier which was called 43 times, avg 21µs/call:
# 43 times (460µs+453µs) by Class::MOP::Class::add_around_method_modifier at line 1109 of Class/MOP/Class.pm, avg 21µs/call | ||||
163 | 215 | 352µs | my $code = shift; | ||
164 | my $modifier = shift; | ||||
165 | unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier; | ||||
166 | $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->( | ||||
167 | 43 | 309µs | @{$code->{'modifier_table'}->{around}->{methods}}, # spent 309µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:160], avg 7µs/call | ||
168 | $code->{'modifier_table'}->{orig} | ||||
169 | ); | ||||
170 | 43 | 144µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 144µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:64], avg 3µs/call | ||
171 | } | ||||
172 | } | ||||
173 | |||||
174 | sub around_modifiers { | ||||
175 | my $code = shift; | ||||
176 | return @{$code->{'modifier_table'}->{around}->{methods}}; | ||||
177 | } | ||||
178 | |||||
179 | sub _make_compatible_with { | ||||
180 | my $self = shift; | ||||
181 | my ($other) = @_; | ||||
182 | |||||
183 | # XXX: this is pretty gross. the issue here is that CMOP::Method::Wrapped | ||||
184 | # objects are subclasses of CMOP::Method, but when we get to moose, they'll | ||||
185 | # need to be compatible with Moose::Meta::Method, which isn't possible. the | ||||
186 | # right solution here is to make ::Wrapped into a role that gets applied to | ||||
187 | # whatever the method_metaclass happens to be and get rid of | ||||
188 | # wrapped_method_metaclass entirely, but that's not going to happen until | ||||
189 | # we ditch cmop and get roles into the bootstrapping, so. i'm not | ||||
190 | # maintaining the previous behavior of turning them into instances of the | ||||
191 | # new method_metaclass because that's equally broken, and at least this way | ||||
192 | # any issues will at least be detectable and potentially fixable. -doy | ||||
193 | return $self unless $other->_is_compatible_with($self->_real_ref_name); | ||||
194 | |||||
195 | return $self->SUPER::_make_compatible_with(@_); | ||||
196 | } | ||||
197 | |||||
198 | 1 | 8µs | 1; | ||
199 | |||||
200 | # ABSTRACT: Method Meta Object for methods with before/after/around modifiers | ||||
201 | |||||
202 | __END__ |