Filename | /opt/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm |
Statements | Executed 2657 statements in 11.4ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
44 | 1 | 1 | 4.30ms | 4.76ms | add_around_modifier | Class::MOP::Method::Wrapped::
660 | 1 | 1 | 2.18ms | 12.5ms | __ANON__[:162] | Class::MOP::Method::Wrapped::
44 | 1 | 1 | 1.04ms | 2.56ms | wrap | Class::MOP::Method::Wrapped::
88 | 2 | 1 | 330µs | 330µs | __ANON__[:71] | Class::MOP::Method::Wrapped::
44 | 1 | 1 | 308µs | 308µs | __ANON__[:164] | Class::MOP::Method::Wrapped::
44 | 1 | 1 | 305µs | 305µs | _new | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 11µs | 11µs | BEGIN@3 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 9µs | 14µs | BEGIN@11 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 9µs | 41µs | BEGIN@13 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 9µs | 86µs | BEGIN@16 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 9µs | 36µs | BEGIN@14 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 8µs | 24µs | BEGIN@10 | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:45] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:51] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:66] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:91] | 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 | add_before_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 | |||||
2 | package Class::MOP::Method::Wrapped; | ||||
3 | # spent 11µs within Class::MOP::Method::Wrapped::BEGIN@3 which was called:
# once (11µs+0s) by Class::MOP::Class::BEGIN@14 at line 5 | ||||
4 | 1 | 6µs | $Class::MOP::Method::Wrapped::AUTHORITY = 'cpan:STEVAN'; | ||
5 | 1 | 41µs | 1 | 11µs | } # spent 11µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@3 |
6 | { | ||||
7 | 2 | 1µs | $Class::MOP::Method::Wrapped::VERSION = '2.1005'; | ||
8 | } | ||||
9 | |||||
10 | 2 | 30µs | 2 | 40µs | # spent 24µs (8+16) within Class::MOP::Method::Wrapped::BEGIN@10 which was called:
# once (8µs+16µs) by Class::MOP::Class::BEGIN@14 at line 10 # spent 24µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@10
# spent 16µs making 1 call to strict::import |
11 | 2 | 40µs | 2 | 19µs | # spent 14µs (9+5) within Class::MOP::Method::Wrapped::BEGIN@11 which was called:
# once (9µs+5µs) by Class::MOP::Class::BEGIN@14 at line 11 # spent 14µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@11
# spent 5µs making 1 call to warnings::import |
12 | |||||
13 | 2 | 34µs | 2 | 72µs | # spent 41µs (9+32) within Class::MOP::Method::Wrapped::BEGIN@13 which was called:
# once (9µs+32µs) by Class::MOP::Class::BEGIN@14 at line 13 # spent 41µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@13
# spent 32µs making 1 call to Exporter::import |
14 | 2 | 35µs | 2 | 63µs | # spent 36µs (9+27) within Class::MOP::Method::Wrapped::BEGIN@14 which was called:
# once (9µs+27µs) by Class::MOP::Class::BEGIN@14 at line 14 # spent 36µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@14
# spent 27µs making 1 call to Exporter::import |
15 | |||||
16 | 2 | 1.19ms | 2 | 164µs | # spent 86µs (9+77) within Class::MOP::Method::Wrapped::BEGIN@16 which was called:
# once (9µs+77µs) by Class::MOP::Class::BEGIN@14 at line 16 # spent 86µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@16
# spent 77µ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 330µs within Class::MOP::Method::Wrapped::__ANON__[/opt/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:71] which was called 88 times, avg 4µs/call:
# 44 times (175µs+0s) by Class::MOP::Method::Wrapped::wrap at line 89, avg 4µs/call
# 44 times (156µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 174, avg 4µs/call | ||||
25 | 88 | 17µs | my $modifier_table = shift; | ||
26 | 88 | 68µs | my ($before, $after, $around) = ( | ||
27 | $modifier_table->{before}, | ||||
28 | $modifier_table->{after}, | ||||
29 | $modifier_table->{around}, | ||||
30 | ); | ||||
31 | 88 | 4.12ms | if (@$before && @$after) { | ||
32 | $modifier_table->{cache} = sub { | ||||
33 | for my $c (@$before) { $c->(@_) }; | ||||
34 | my @rval; | ||||
35 | ((defined wantarray) ? | ||||
36 | ((wantarray) ? | ||||
37 | (@rval = $around->{cache}->(@_)) | ||||
38 | : | ||||
39 | ($rval[0] = $around->{cache}->(@_))) | ||||
40 | : | ||||
41 | $around->{cache}->(@_)); | ||||
42 | for my $c (@$after) { $c->(@_) }; | ||||
43 | return unless defined wantarray; | ||||
44 | return wantarray ? @rval : $rval[0]; | ||||
45 | } | ||||
46 | } | ||||
47 | elsif (@$before && !@$after) { | ||||
48 | $modifier_table->{cache} = sub { | ||||
49 | for my $c (@$before) { $c->(@_) }; | ||||
50 | return $around->{cache}->(@_); | ||||
51 | } | ||||
52 | } | ||||
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 | 88 | 38µs | $modifier_table->{cache} = $around->{cache}; | ||
70 | } | ||||
71 | 1 | 3µs | }; | ||
72 | |||||
73 | # spent 2.56ms (1.04+1.52) within Class::MOP::Method::Wrapped::wrap which was called 44 times, avg 58µs/call:
# 44 times (1.04ms+1.52ms) by Class::MOP::Class::__ANON__[/opt/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level/Class/MOP/Class.pm:1072] at line 1058 of Class/MOP/Class.pm, avg 58µs/call | ||||
74 | 44 | 83µs | my ( $class, $code, %params ) = @_; | ||
75 | |||||
76 | 44 | 220µs | 88 | 58µs | (blessed($code) && $code->isa('Class::MOP::Method')) # spent 30µs making 44 calls to Scalar::Util::blessed, avg 684ns/call
# spent 28µs making 44 calls to UNIVERSAL::isa, avg 625ns/call |
77 | || confess "Can only wrap blessed CODE"; | ||||
78 | |||||
79 | 44 | 324µs | 88 | 44µs | my $modifier_table = { # spent 44µs making 88 calls to Class::MOP::Method::body, avg 494ns/call |
80 | cache => undef, | ||||
81 | orig => $code->body, | ||||
82 | before => [], | ||||
83 | after => [], | ||||
84 | around => { | ||||
85 | cache => $code->body, | ||||
86 | methods => [], | ||||
87 | }, | ||||
88 | }; | ||||
89 | 44 | 55µs | 44 | 175µs | $_build_wrapped_method->($modifier_table); # spent 175µs making 44 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71], avg 4µs/call |
90 | return $class->SUPER::wrap( | ||||
91 | 660 | 1.90ms | 660 | 12.5ms | sub { $modifier_table->{cache}->(@_) }, # spent 12.5ms making 660 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:162], avg 19µs/call |
92 | # get these from the original | ||||
93 | # unless explicitly overridden | ||||
94 | 44 | 388µs | 44 | 1.24ms | package_name => $params{package_name} || $code->package_name, # spent 1.24ms making 44 calls to Class::MOP::Method::wrap, avg 28µs/call |
95 | name => $params{name} || $code->name, | ||||
96 | original_method => $code, | ||||
97 | |||||
98 | modifier_table => $modifier_table, | ||||
99 | ); | ||||
100 | } | ||||
101 | |||||
102 | # spent 305µs within Class::MOP::Method::Wrapped::_new which was called 44 times, avg 7µs/call:
# 44 times (305µs+0s) by Class::MOP::Method::wrap at line 46 of Class/MOP/Method.pm, avg 7µs/call | ||||
103 | 44 | 12µs | my $class = shift; | ||
104 | 44 | 13µs | return Class::MOP::Class->initialize($class)->new_object(@_) | ||
105 | if $class ne __PACKAGE__; | ||||
106 | |||||
107 | 44 | 19µs | my $params = @_ == 1 ? $_[0] : {@_}; | ||
108 | |||||
109 | 44 | 296µ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 | sub add_before_modifier { | ||||
128 | my $code = shift; | ||||
129 | my $modifier = shift; | ||||
130 | unshift @{$code->{'modifier_table'}->{before}} => $modifier; | ||||
131 | $_build_wrapped_method->($code->{'modifier_table'}); | ||||
132 | } | ||||
133 | |||||
134 | sub before_modifiers { | ||||
135 | my $code = shift; | ||||
136 | return @{$code->{'modifier_table'}->{before}}; | ||||
137 | } | ||||
138 | |||||
139 | sub add_after_modifier { | ||||
140 | my $code = shift; | ||||
141 | my $modifier = shift; | ||||
142 | push @{$code->{'modifier_table'}->{after}} => $modifier; | ||||
143 | $_build_wrapped_method->($code->{'modifier_table'}); | ||||
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 | 89 | 19µs | # spent 308µs within Class::MOP::Method::Wrapped::__ANON__[/opt/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:164] which was called 44 times, avg 7µs/call:
# 44 times (308µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 171, avg 7µs/call | ||
159 | 44 | 6µs | my $f1 = pop; | ||
160 | 88 | 158µs | return $f1 unless @_; | ||
161 | 44 | 5µs | my $f2 = pop; | ||
162 | 704 | 1.98ms | 660 | 10.3ms | # spent 12.5ms (2.18+10.3) within Class::MOP::Method::Wrapped::__ANON__[/opt/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm:162] which was called 660 times, avg 19µs/call:
# 660 times (2.18ms+10.3ms) 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 91, avg 19µs/call # spent 10.3ms making 660 calls to Class::MOP::Class:::around, avg 16µs/call |
163 | 44 | 15µs | redo; | ||
164 | 1 | 2µs | }}; | ||
165 | |||||
166 | # spent 4.76ms (4.30+463µs) within Class::MOP::Method::Wrapped::add_around_modifier which was called 44 times, avg 108µs/call:
# 44 times (4.30ms+463µs) by Class::MOP::Class::add_around_method_modifier at line 1099 of Class/MOP/Class.pm, avg 108µs/call | ||||
167 | 44 | 9µs | my $code = shift; | ||
168 | 44 | 5µs | my $modifier = shift; | ||
169 | 44 | 55µs | unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier; | ||
170 | $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->( | ||||
171 | 44 | 102µs | 44 | 308µs | @{$code->{'modifier_table'}->{around}->{methods}}, # spent 308µs making 44 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:164], avg 7µs/call |
172 | $code->{'modifier_table'}->{orig} | ||||
173 | ); | ||||
174 | 44 | 149µs | 44 | 156µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 156µs making 44 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:71], avg 4µ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 | 5µs | 1; | ||
203 | |||||
204 | # ABSTRACT: Method Meta Object for methods with before/after/around modifiers | ||||
205 | |||||
206 | __END__ |