Filename | /usr/share/perl5/Sub/Quote.pm |
Statements | Executed 1133 statements in 4.83ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
18 | 1 | 1 | 6.22ms | 6.79ms | _clean_eval | Sub::Quote::
44 | 5 | 2 | 1.06ms | 2.24ms | quote_sub | Sub::Quote::
18 | 2 | 2 | 462µs | 7.59ms | unquote_sub | Sub::Quote::
18 | 1 | 1 | 263µs | 335µs | capture_unroll | Sub::Quote::
24 | 1 | 1 | 37µs | 37µs | CORE:match (opcode) | Sub::Quote::
8 | 1 | 1 | 36µs | 2.27ms | __ANON__[:82] | Sub::Quote::
1 | 1 | 1 | 18µs | 64µs | BEGIN@7 | Sub::Quote::
1 | 1 | 1 | 17µs | 70µs | BEGIN@3 | Sub::Quote::
6 | 1 | 1 | 13µs | 13µs | quoted_from_sub | Sub::Quote::
1 | 1 | 1 | 11µs | 41µs | BEGIN@8 | Sub::Quote::
1 | 1 | 1 | 11µs | 83µs | BEGIN@10 | Sub::Quote::
1 | 1 | 1 | 11µs | 38µs | BEGIN@9 | Sub::Quote::
1 | 1 | 1 | 10µs | 27µs | BEGIN@120 | Sub::Quote::
0 | 0 | 0 | 0s | 0s | CLONE | Sub::Quote::
0 | 0 | 0 | 0s | 0s | inlinify | Sub::Quote::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Sub::Quote; | ||||
2 | |||||
3 | 3 | 62µs | 3 | 122µs | # spent 70µs (17+52) within Sub::Quote::BEGIN@3 which was called:
# once (17µs+52µs) by Method::Generate::Constructor::BEGIN@4 at line 3 # spent 70µs making 1 call to Sub::Quote::BEGIN@3
# spent 35µs making 1 call to strictures::import
# spent 17µs making 1 call to strictures::VERSION |
4 | |||||
5 | 18 | 1.50ms | # spent 6.79ms (6.22+578µs) within Sub::Quote::_clean_eval which was called 18 times, avg 378µs/call:
# 18 times (6.22ms+578µs) by Sub::Quote::unquote_sub at line 125, avg 378µs/call # spent 613µs executing statements in string eval # includes 72µs spent executing 4 calls to 3 subs defined therein. # spent 518µs executing statements in string eval # includes 151µs spent executing 12 calls to 3 subs defined therein. # spent 471µs executing statements in string eval # includes 56µs spent executing 4 calls to 3 subs defined therein. # spent 429µs executing statements in string eval # includes 42µs spent executing 4 calls to 3 subs defined therein. # spent 402µs executing statements in string eval # includes 54µs spent executing 4 calls to 3 subs defined therein. # spent 397µs executing statements in string eval # includes 47µs spent executing 4 calls to 3 subs defined therein. # spent 393µs executing statements in string eval # includes 46µs spent executing 4 calls to 3 subs defined therein. # spent 363µs executing statements in string eval # includes 41µs spent executing 4 calls to 3 subs defined therein. # spent 335µs executing statements in string eval # includes 43µs spent executing 4 calls to 3 subs defined therein. # spent 313µs executing statements in string eval # includes 44µs spent executing 4 calls to 3 subs defined therein. # spent 197µs executing statements in string eval # includes 58µs spent executing 12 calls to 3 subs defined therein. # spent 188µs executing statements in string eval # includes 47µs spent executing 6 calls to 3 subs defined therein. # spent 166µs executing statements in string eval # includes 35µs spent executing 4 calls to 3 subs defined therein. # spent 159µs executing statements in string eval # includes 68µs spent executing 6 calls to 3 subs defined therein. # spent 156µs executing statements in string eval # includes 81µs spent executing 10 calls to 3 subs defined therein. # spent 155µs executing statements in string eval # includes 35µs spent executing 6 calls to 3 subs defined therein. # spent 150µs executing statements in string eval # includes 33µs spent executing 4 calls to 3 subs defined therein. # spent 119µs executing statements in string eval # includes 35µs spent executing 4 calls to 3 subs defined therein. | ||
6 | |||||
7 | 2 | 44µs | 2 | 111µs | # spent 64µs (18+46) within Sub::Quote::BEGIN@7 which was called:
# once (18µs+46µs) by Method::Generate::Constructor::BEGIN@4 at line 7 # spent 64µs making 1 call to Sub::Quote::BEGIN@7
# spent 46µs making 1 call to Exporter::import |
8 | 2 | 34µs | 2 | 71µs | # spent 41µs (11+30) within Sub::Quote::BEGIN@8 which was called:
# once (11µs+30µs) by Method::Generate::Constructor::BEGIN@4 at line 8 # spent 41µs making 1 call to Sub::Quote::BEGIN@8
# spent 30µs making 1 call to Exporter::import |
9 | 2 | 34µs | 2 | 66µs | # spent 38µs (11+28) within Sub::Quote::BEGIN@9 which was called:
# once (11µs+28µs) by Method::Generate::Constructor::BEGIN@4 at line 9 # spent 38µs making 1 call to Sub::Quote::BEGIN@9
# spent 28µs making 1 call to Exporter::import |
10 | 2 | 792µs | 2 | 156µs | # spent 83µs (11+72) within Sub::Quote::BEGIN@10 which was called:
# once (11µs+72µs) by Method::Generate::Constructor::BEGIN@4 at line 10 # spent 83µs making 1 call to Sub::Quote::BEGIN@10
# spent 72µs making 1 call to base::import |
11 | |||||
12 | 1 | 700ns | our $VERSION = '1.004002'; | ||
13 | 1 | 13µs | $VERSION = eval $VERSION; # spent 2µs executing statements in string eval | ||
14 | |||||
15 | 1 | 1µs | our @EXPORT = qw(quote_sub unquote_sub quoted_from_sub); | ||
16 | |||||
17 | 1 | 200ns | our %QUOTED; | ||
18 | |||||
19 | 1 | 100ns | our %WEAK_REFS; | ||
20 | |||||
21 | # spent 335µs (263+73) within Sub::Quote::capture_unroll which was called 18 times, avg 19µs/call:
# 18 times (263µs+73µs) by Sub::Quote::unquote_sub at line 102, avg 19µs/call | ||||
22 | 18 | 9µs | my ($from, $captures, $indent) = @_; | ||
23 | 24 | 94µs | 24 | 37µs | join( # spent 37µs making 24 calls to Sub::Quote::CORE:match, avg 2µs/call |
24 | '', | ||||
25 | map { | ||||
26 | 18 | 90µs | /^([\@\%\$])/ | ||
27 | or die "capture key should start with \@, \% or \$: $_"; | ||||
28 | 48 | 164µs | 24 | 35µs | (' ' x $indent).qq{my ${_} = ${1}{${from}->{${\perlstring $_}}};\n}; # spent 35µs making 24 calls to B::perlstring, avg 1µs/call |
29 | } keys %$captures | ||||
30 | ); | ||||
31 | } | ||||
32 | |||||
33 | sub inlinify { | ||||
34 | my ($code, $args, $extra, $local) = @_; | ||||
35 | my $do = 'do { '.($extra||''); | ||||
36 | if ($code =~ s/^(\s*package\s+([a-zA-Z0-9:]+);)//) { | ||||
37 | $do .= $1; | ||||
38 | } | ||||
39 | my $assign = ''; | ||||
40 | if (my ($code_args) = $code =~ /^\s*my\s*\(([^)]+)\)\s*=\s*\@_;$/s) { | ||||
41 | if ($code_args ne $args) { | ||||
42 | $assign = 'my ('.$code_args.') = ('.$args.'); '; | ||||
43 | } | ||||
44 | } | ||||
45 | elsif ($local || $args ne '@_') { | ||||
46 | $assign = ($local ? 'local ' : '').'@_ = ('.$args.'); '; | ||||
47 | } | ||||
48 | $do.$assign.$code.' }'; | ||||
49 | } | ||||
50 | |||||
51 | # spent 2.24ms (1.06+1.18) within Sub::Quote::quote_sub which was called 44 times, avg 51µs/call:
# 18 times (378µs+517µs) by Method::Generate::Accessor::generate_method at line 206 of Method/Generate/Accessor.pm, avg 50µs/call
# 13 times (334µs+409µs) by Method::Generate::Accessor::generate_method at line 115 of Method/Generate/Accessor.pm, avg 57µs/call
# 10 times (278µs+162µs) by Method::Generate::Constructor::generate_method at line 109 of Method/Generate/Constructor.pm, avg 44µs/call
# 2 times (49µs+62µs) by Method::Generate::Accessor::generate_method at line 217 of Method/Generate/Accessor.pm, avg 56µs/call
# once (20µs+26µs) by Method::Generate::Accessor::generate_method at line 182 of Method/Generate/Accessor.pm | ||||
52 | # HOLY DWIMMERY, BATMAN! | ||||
53 | # $name => $code => \%captures => \%options | ||||
54 | # $name => $code => \%captures | ||||
55 | # $name => $code | ||||
56 | # $code => \%captures => \%options | ||||
57 | # $code | ||||
58 | 44 | 57µs | my $options = | ||
59 | (ref($_[-1]) eq 'HASH' and ref($_[-2]) eq 'HASH') | ||||
60 | ? pop | ||||
61 | : {}; | ||||
62 | 44 | 19µs | my $captures = ref($_[-1]) eq 'HASH' ? pop : undef; | ||
63 | 44 | 38µs | undef($captures) if $captures && !keys %$captures; | ||
64 | 44 | 17µs | my $code = pop; | ||
65 | 44 | 11µs | my $name = $_[0]; | ||
66 | 44 | 116µs | my ($package, $hints, $bitmask, $hintshash) = (caller(0))[0,8,9,10]; | ||
67 | 44 | 484µs | 88 | 207µs | my $context # spent 207µs making 88 calls to B::perlstring, avg 2µs/call |
68 | ="package $package;\n" | ||||
69 | ."BEGIN {\n" | ||||
70 | ." \$^H = ".B::perlstring($hints).";\n" | ||||
71 | ." \${^WARNING_BITS} = ".B::perlstring($bitmask).";\n" | ||||
72 | ." \%^H = (\n" | ||||
73 | . join('', map | ||||
74 | " ".B::perlstring($_)." => ".B::perlstring($hintshash->{$_}).",", | ||||
75 | keys %$hintshash) | ||||
76 | ." );\n" | ||||
77 | ."}\n"; | ||||
78 | 44 | 55µs | $code = "$context$code"; | ||
79 | 44 | 4µs | my $quoted_info; | ||
80 | # spent 2.27ms (36µs+2.23) within Sub::Quote::__ANON__[/usr/share/perl5/Sub/Quote.pm:82] which was called 8 times, avg 284µs/call:
# 8 times (36µs+2.23ms) by Sub::Defer::undefer_sub at line 22 of Sub/Defer.pm, avg 284µs/call | ||||
81 | 8 | 31µs | 8 | 2.23ms | unquote_sub($quoted_info->[4]); # spent 2.23ms making 8 calls to Sub::Quote::unquote_sub, avg 279µs/call |
82 | 44 | 170µs | 44 | 932µs | }; # spent 932µs making 44 calls to Sub::Defer::defer_sub, avg 21µs/call |
83 | 44 | 64µs | $quoted_info = [ $name, $code, $captures, undef, $deferred ]; | ||
84 | 44 | 150µs | 44 | 38µs | weaken($QUOTED{$deferred} = $quoted_info); # spent 38µs making 44 calls to Scalar::Util::weaken, avg 873ns/call |
85 | 44 | 136µs | return $deferred; | ||
86 | } | ||||
87 | |||||
88 | # spent 13µs within Sub::Quote::quoted_from_sub which was called 6 times, avg 2µs/call:
# 6 times (13µs+0s) by Method::Generate::Accessor::_generate_call_code at line 438 of Method/Generate/Accessor.pm, avg 2µs/call | ||||
89 | 6 | 1µs | my ($sub) = @_; | ||
90 | 6 | 17µs | $QUOTED{$sub||''}; | ||
91 | } | ||||
92 | |||||
93 | # spent 7.59ms (462µs+7.13) within Sub::Quote::unquote_sub which was called 18 times, avg 422µs/call:
# 10 times (252µs+5.11ms) by Method::Generate::Constructor::__ANON__[/usr/share/perl5/Method/Generate/Constructor.pm:76] at line 73 of Method/Generate/Constructor.pm, avg 536µs/call
# 8 times (210µs+2.02ms) by Sub::Quote::__ANON__[/usr/share/perl5/Sub/Quote.pm:82] at line 81, avg 279µs/call | ||||
94 | 18 | 5µs | my ($sub) = @_; | ||
95 | 18 | 21µs | unless ($QUOTED{$sub}[3]) { | ||
96 | 18 | 29µs | my ($name, $code, $captures) = @{$QUOTED{$sub}}; | ||
97 | |||||
98 | 18 | 5µs | my $make_sub = "{\n"; | ||
99 | |||||
100 | 18 | 16µs | my %captures = $captures ? %$captures : (); | ||
101 | 18 | 21µs | $captures{'$_QUOTED'} = \$QUOTED{$sub}; | ||
102 | 18 | 32µs | 18 | 335µs | $make_sub .= capture_unroll("\$_[1]", \%captures, 2); # spent 335µs making 18 calls to Sub::Quote::capture_unroll, avg 19µs/call |
103 | |||||
104 | 18 | 13µs | $make_sub .= ( | ||
105 | $name | ||||
106 | # disable the 'variable $x will not stay shared' warning since | ||||
107 | # we're not letting it escape from this scope anyway so there's | ||||
108 | # nothing trying to share it | ||||
109 | ? " no warnings 'closure';\n sub ${name} {\n" | ||||
110 | : " \$_QUOTED->[3] = sub {\n" | ||||
111 | ); | ||||
112 | 18 | 11µs | $make_sub .= $code; | ||
113 | 18 | 12µs | $make_sub .= " }".($name ? '' : ';')."\n"; | ||
114 | 18 | 12µs | if ($name) { | ||
115 | $make_sub .= " \$_QUOTED->[3] = \\&${name}\n"; | ||||
116 | } | ||||
117 | 18 | 3µs | $make_sub .= "}\n1;\n"; | ||
118 | 18 | 10µs | $ENV{SUB_QUOTE_DEBUG} && warn $make_sub; | ||
119 | { | ||||
120 | 20 | 218µs | 2 | 44µs | # spent 27µs (10+17) within Sub::Quote::BEGIN@120 which was called:
# once (10µs+17µs) by Method::Generate::Constructor::BEGIN@4 at line 120 # spent 27µs making 1 call to Sub::Quote::BEGIN@120
# spent 17µs making 1 call to strict::unimport |
121 | 18 | 52µs | local *{$name} if $name; | ||
122 | 18 | 3µs | my ($success, $e); | ||
123 | { | ||||
124 | 36 | 9µs | local $@; | ||
125 | 18 | 33µs | 18 | 6.79ms | $success = _clean_eval($make_sub, \%captures); # spent 6.79ms making 18 calls to Sub::Quote::_clean_eval, avg 378µs/call |
126 | 18 | 13µs | $e = $@; | ||
127 | } | ||||
128 | 18 | 19µs | unless ($success) { | ||
129 | die "Eval went very, very wrong:\n\n${make_sub}\n\n$e"; | ||||
130 | } | ||||
131 | } | ||||
132 | } | ||||
133 | 18 | 71µs | $QUOTED{$sub}[3]; | ||
134 | } | ||||
135 | |||||
136 | sub CLONE { | ||||
137 | %QUOTED = map { defined $_ ? ($_->[4] => $_) : () } values %QUOTED; | ||||
138 | weaken($_) for values %QUOTED; | ||||
139 | } | ||||
140 | |||||
141 | 1 | 4µs | 1; | ||
142 | __END__ | ||||
# spent 37µs within Sub::Quote::CORE:match which was called 24 times, avg 2µs/call:
# 24 times (37µs+0s) by Sub::Quote::capture_unroll at line 23, avg 2µs/call |