| Filename | /home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Sub/Quote.pm |
| Statements | Executed 1808 statements in 4.55ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 17 | 1 | 1 | 4.00ms | 4.43ms | Sub::Quote::_clean_eval |
| 44 | 5 | 2 | 707µs | 1.49ms | Sub::Quote::quote_sub |
| 469 | 11 | 3 | 456µs | 695µs | Sub::Quote::quotify |
| 1 | 1 | 1 | 429µs | 543µs | Sub::Quote::BEGIN@7 |
| 17 | 2 | 2 | 417µs | 5.21ms | Sub::Quote::unquote_sub |
| 17 | 1 | 1 | 234µs | 345µs | Sub::Quote::capture_unroll |
| 39 | 1 | 1 | 29µs | 29µs | Sub::Quote::CORE:match (opcode) |
| 7 | 1 | 1 | 25µs | 1.63ms | Sub::Quote::__ANON__[:98] |
| 5 | 1 | 1 | 11µs | 11µs | Sub::Quote::quoted_from_sub |
| 1 | 1 | 1 | 6µs | 14µs | Sub::Quote::BEGIN@5 |
| 1 | 1 | 1 | 6µs | 16µs | Sub::Quote::BEGIN@150 |
| 1 | 1 | 1 | 6µs | 11µs | Sub::Quote::BEGIN@9 |
| 1 | 1 | 1 | 6µs | 26µs | Sub::Quote::BEGIN@8 |
| 1 | 1 | 1 | 3µs | 3µs | Sub::Quote::BEGIN@11 |
| 1 | 1 | 1 | 3µs | 3µs | Sub::Quote::BEGIN@10 |
| 0 | 0 | 0 | 0s | 0s | Sub::Quote::CLONE |
| 0 | 0 | 0 | 0s | 0s | Sub::Quote::inlinify |
| 0 | 0 | 0 | 0s | 0s | Sub::Quote::qsub |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Sub::Quote; | ||||
| 2 | |||||
| 3 | 17 | 1.18ms | # spent 4.43ms (4.00+434µs) within Sub::Quote::_clean_eval which was called 17 times, avg 261µs/call:
# 17 times (4.00ms+434µs) by Sub::Quote::unquote_sub at line 155, avg 261µs/call # spent 45.0ms executing statements in string eval # includes 44.6ms spent executing 1004 calls to 3 subs defined therein. # spent 29.2ms executing statements in string eval # includes 65.3ms spent executing 4006 calls to 3 subs defined therein. # spent 25.5ms executing statements in string eval # includes 68.4ms spent executing 8010 calls to 3 subs defined therein. # spent 25.0ms executing statements in string eval # includes 36.4ms spent executing 1004 calls to 3 subs defined therein. # spent 23.1ms executing statements in string eval # includes 18.7ms spent executing 10012 calls to 3 subs defined therein. # spent 19.2ms executing statements in string eval # includes 24.4ms spent executing 1004 calls to 3 subs defined therein. # spent 18.8ms executing statements in string eval # includes 17.8ms spent executing 1004 calls to 3 subs defined therein. # spent 18.4ms executing statements in string eval # includes 17.3ms spent executing 1004 calls to 3 subs defined therein. # spent 18.1ms executing statements in string eval # includes 13.8ms spent executing 4006 calls to 3 subs defined therein. # spent 16.3ms executing statements in string eval # includes 21.9ms spent executing 1003 calls to 3 subs defined therein. # spent 15.8ms executing statements in string eval # includes 14.8ms spent executing 1004 calls to 3 subs defined therein. # spent 8.35ms executing statements in string eval # includes 11.1ms spent executing 4006 calls to 3 subs defined therein. # spent 4.34ms executing statements in string eval # includes 16.5ms spent executing 2004 calls to 3 subs defined therein. # spent 410µs executing statements in string eval # includes 182µs spent executing 14 calls to 3 subs defined therein. # spent 255µs executing statements in string eval # includes 29µs spent executing 4 calls to 3 subs defined therein. # spent 240µs executing statements in string eval # includes 32µs spent executing 4 calls to 3 subs defined therein. # spent 138µs executing statements in string eval # includes 38µs spent executing 4 calls to 3 subs defined therein. | ||
| 4 | |||||
| 5 | 2 | 14µs | 2 | 22µs | # spent 14µs (6+8) within Sub::Quote::BEGIN@5 which was called:
# once (6µs+8µs) by Moo::HandleMoose::BEGIN@5 at line 5 # spent 14µs making 1 call to Sub::Quote::BEGIN@5
# spent 8µs making 1 call to Moo::_strictures::import |
| 6 | |||||
| 7 | 2 | 60µs | 2 | 565µs | # spent 543µs (429+114) within Sub::Quote::BEGIN@7 which was called:
# once (429µs+114µs) by Moo::HandleMoose::BEGIN@5 at line 7 # spent 543µs making 1 call to Sub::Quote::BEGIN@7
# spent 22µs making 1 call to Exporter::import |
| 8 | 2 | 32µs | 2 | 48µs | # spent 26µs (6+21) within Sub::Quote::BEGIN@8 which was called:
# once (6µs+21µs) by Moo::HandleMoose::BEGIN@5 at line 8 # spent 26µs making 1 call to Sub::Quote::BEGIN@8
# spent 21µs making 1 call to Exporter::import |
| 9 | 2 | 22µs | 2 | 15µs | # spent 11µs (6+5) within Sub::Quote::BEGIN@9 which was called:
# once (6µs+5µs) by Moo::HandleMoose::BEGIN@5 at line 9 # spent 11µs making 1 call to Sub::Quote::BEGIN@9
# spent 5µs making 1 call to Exporter::import |
| 10 | 2 | 58µs | 1 | 3µs | # spent 3µs within Sub::Quote::BEGIN@10 which was called:
# once (3µs+0s) by Moo::HandleMoose::BEGIN@5 at line 10 # spent 3µs making 1 call to Sub::Quote::BEGIN@10 |
| 11 | # spent 3µs within Sub::Quote::BEGIN@11 which was called:
# once (3µs+0s) by Moo::HandleMoose::BEGIN@5 at line 13 | ||||
| 12 | 1 | 3µs | *_HAVE_PERLSTRING = defined &B::perlstring ? sub(){1} : sub(){0}; | ||
| 13 | 1 | 699µs | 1 | 3µs | } # spent 3µs making 1 call to Sub::Quote::BEGIN@11 |
| 14 | |||||
| 15 | 1 | 300ns | our $VERSION = '2.000002'; | ||
| 16 | 1 | 9µs | $VERSION = eval $VERSION; # spent 2µs executing statements in string eval | ||
| 17 | |||||
| 18 | 1 | 800ns | our @EXPORT = qw(quote_sub unquote_sub quoted_from_sub qsub); | ||
| 19 | 1 | 400ns | our @EXPORT_OK = qw(quotify capture_unroll inlinify); | ||
| 20 | |||||
| 21 | our %QUOTED; | ||||
| 22 | |||||
| 23 | # spent 695µs (456+239) within Sub::Quote::quotify which was called 469 times, avg 1µs/call:
# 88 times (82µs+66µs) by Sub::Quote::quote_sub at line 87, avg 2µs/call
# 86 times (72µs+31µs) by Method::Generate::Accessor::_generate_simple_set at line 575 of Method/Generate/Accessor.pm, avg 1µs/call
# 86 times (68µs+29µs) by Method::Generate::Accessor::_generate_core_set at line 569 of Method/Generate/Accessor.pm, avg 1µs/call
# 71 times (63µs+29µs) by Method::Generate::Constructor::_assign_new at line 214 of Method/Generate/Constructor.pm, avg 1µs/call
# 39 times (53µs+28µs) by Sub::Quote::capture_unroll at line 36, avg 2µs/call
# 30 times (36µs+16µs) by Method::Generate::Accessor::_generate_simple_get at line 339 of Method/Generate/Accessor.pm, avg 2µs/call
# 22 times (20µs+9µs) by Method::Generate::Accessor::_generate_get_default at line 320 of Method/Generate/Accessor.pm, avg 1µs/call
# 19 times (18µs+8µs) by Method::Generate::Constructor::_check_required at line 233 of Method/Generate/Constructor.pm, avg 1µs/call
# 17 times (16µs+7µs) by Method::Generate::Accessor::_generate_simple_has at line 276 of Method/Generate/Accessor.pm, avg 1µs/call
# 10 times (28µs+16µs) by Method::Generate::Constructor::_handle_subconstructor at line 158 of Method/Generate/Constructor.pm, avg 4µs/call
# once (1µs+400ns) by Method::Generate::Accessor::_generate_simple_clear at line 281 of Method/Generate/Accessor.pm | ||||
| 24 | 469 | 954µs | 469 | 239µs | ! defined $_[0] ? 'undef()' # spent 239µs making 469 calls to B::perlstring, avg 509ns/call |
| 25 | : _HAVE_PERLSTRING ? B::perlstring($_[0]) | ||||
| 26 | : qq["\Q$_[0]\E"]; | ||||
| 27 | } | ||||
| 28 | |||||
| 29 | # spent 345µs (234+110) within Sub::Quote::capture_unroll which was called 17 times, avg 20µs/call:
# 17 times (234µs+110µs) by Sub::Quote::unquote_sub at line 130, avg 20µs/call | ||||
| 30 | 17 | 8µs | my ($from, $captures, $indent) = @_; | ||
| 31 | join( | ||||
| 32 | '', | ||||
| 33 | map { | ||||
| 34 | 56 | 138µs | 39 | 29µs | /^([\@\%\$])/ # spent 29µs making 39 calls to Sub::Quote::CORE:match, avg 751ns/call |
| 35 | or die "capture key should start with \@, \% or \$: $_"; | ||||
| 36 | 78 | 108µs | 39 | 81µs | (' ' x $indent).qq{my ${_} = ${1}{${from}->{${\quotify $_}}};\n}; # spent 81µs making 39 calls to Sub::Quote::quotify, avg 2µs/call |
| 37 | } keys %$captures | ||||
| 38 | ); | ||||
| 39 | } | ||||
| 40 | |||||
| 41 | sub inlinify { | ||||
| 42 | my ($code, $args, $extra, $local) = @_; | ||||
| 43 | my $do = 'do { '.($extra||''); | ||||
| 44 | if ($code =~ s/^(\s*package\s+([a-zA-Z0-9:]+);)//) { | ||||
| 45 | $do .= $1; | ||||
| 46 | } | ||||
| 47 | if ($code =~ s{ | ||||
| 48 | \A((?:\#\ BEGIN\ quote_sub\ PRELUDE\n.*?\#\ END\ quote_sub\ PRELUDE\n)?\s*) | ||||
| 49 | (^\s*) my \s* \(([^)]+)\) \s* = \s* \@_; | ||||
| 50 | }{}xms) { | ||||
| 51 | my ($pre, $indent, $code_args) = ($1, $2, $3); | ||||
| 52 | $do .= $pre; | ||||
| 53 | if ($code_args ne $args) { | ||||
| 54 | $do .= $indent . 'my ('.$code_args.') = ('.$args.'); '; | ||||
| 55 | } | ||||
| 56 | } | ||||
| 57 | elsif ($local || $args ne '@_') { | ||||
| 58 | $do .= ($local ? 'local ' : '').'@_ = ('.$args.'); '; | ||||
| 59 | } | ||||
| 60 | $do.$code.' }'; | ||||
| 61 | } | ||||
| 62 | |||||
| 63 | # spent 1.49ms (707µs+783µs) within Sub::Quote::quote_sub which was called 44 times, avg 34µs/call:
# 18 times (204µs+320µs) by Method::Generate::Accessor::generate_method at line 211 of Method/Generate/Accessor.pm, avg 29µs/call
# 13 times (216µs+281µs) by Method::Generate::Accessor::generate_method at line 121 of Method/Generate/Accessor.pm, avg 38µs/call
# 10 times (246µs+124µs) by Method::Generate::Constructor::generate_method at line 152 of Method/Generate/Constructor.pm, avg 37µs/call
# 2 times (30µs+37µs) by Method::Generate::Accessor::generate_method at line 221 of Method/Generate/Accessor.pm, avg 34µs/call
# once (12µs+20µs) by Method::Generate::Accessor::generate_method at line 183 of Method/Generate/Accessor.pm | ||||
| 64 | # HOLY DWIMMERY, BATMAN! | ||||
| 65 | # $name => $code => \%captures => \%options | ||||
| 66 | # $name => $code => \%captures | ||||
| 67 | # $name => $code | ||||
| 68 | # $code => \%captures => \%options | ||||
| 69 | # $code | ||||
| 70 | 44 | 26µs | my $options = | ||
| 71 | (ref($_[-1]) eq 'HASH' and ref($_[-2]) eq 'HASH') | ||||
| 72 | ? pop | ||||
| 73 | : {}; | ||||
| 74 | 44 | 11µs | my $captures = ref($_[-1]) eq 'HASH' ? pop : undef; | ||
| 75 | 44 | 19µs | undef($captures) if $captures && !keys %$captures; | ||
| 76 | 44 | 19µs | my $code = pop; | ||
| 77 | 44 | 7µs | my $name = $_[0]; | ||
| 78 | 44 | 102µs | my ($package, $hints, $bitmask, $hintshash) = (caller(0))[0,8,9,10]; | ||
| 79 | my $context | ||||
| 80 | ="# BEGIN quote_sub PRELUDE\n" | ||||
| 81 | ."package $package;\n" | ||||
| 82 | ."BEGIN {\n" | ||||
| 83 | ." \$^H = ".quotify($hints).";\n" | ||||
| 84 | ." \${^WARNING_BITS} = ".quotify($bitmask).";\n" | ||||
| 85 | ." \%^H = (\n" | ||||
| 86 | . join('', map | ||||
| 87 | 44 | 98µs | 88 | 147µs | " ".quotify($_)." => ".quotify($hintshash->{$_}).",", # spent 147µs making 88 calls to Sub::Quote::quotify, avg 2µs/call |
| 88 | keys %$hintshash) | ||||
| 89 | ." );\n" | ||||
| 90 | ."}\n" | ||||
| 91 | ."# END quote_sub PRELUDE\n"; | ||||
| 92 | 44 | 40µs | $code = "$context$code"; | ||
| 93 | 44 | 7µs | my $quoted_info; | ||
| 94 | my $unquoted; | ||||
| 95 | # spent 1.63ms (25µs+1.61) within Sub::Quote::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Sub/Quote.pm:98] which was called 7 times, avg 233µs/call:
# 7 times (25µs+1.61ms) by Sub::Defer::undefer_sub at line 23 of Sub/Defer.pm, avg 233µs/call | ||||
| 96 | $unquoted if 0; | ||||
| 97 | 7 | 22µs | 7 | 1.61ms | unquote_sub($quoted_info->[4]); # spent 1.61ms making 7 calls to Sub::Quote::unquote_sub, avg 230µs/call |
| 98 | 44 | 71µs | 44 | 596µs | }; # spent 596µs making 44 calls to Sub::Defer::defer_sub, avg 14µs/call |
| 99 | 44 | 27µs | $quoted_info = [ $name, $code, $captures, \$unquoted, $deferred ]; | ||
| 100 | 44 | 62µs | 44 | 17µs | weaken($quoted_info->[3]); # spent 17µs making 44 calls to Scalar::Util::weaken, avg 377ns/call |
| 101 | 44 | 51µs | 44 | 13µs | weaken($quoted_info->[4]); # spent 13µs making 44 calls to Scalar::Util::weaken, avg 300ns/call |
| 102 | 44 | 73µs | 44 | 10µs | weaken($QUOTED{$deferred} = $quoted_info); # spent 10µs making 44 calls to Scalar::Util::weaken, avg 223ns/call |
| 103 | 44 | 74µs | return $deferred; | ||
| 104 | } | ||||
| 105 | |||||
| 106 | # spent 11µs within Sub::Quote::quoted_from_sub which was called 5 times, avg 2µs/call:
# 5 times (11µs+0s) by Method::Generate::Accessor::_generate_call_code at line 465 of Method/Generate/Accessor.pm, avg 2µs/call | ||||
| 107 | 5 | 1µs | my ($sub) = @_; | ||
| 108 | 5 | 11µs | my $quoted_info = $QUOTED{$sub||''} or return undef; | ||
| 109 | my ($name, $code, $captured, $unquoted, $deferred) = @{$quoted_info}; | ||||
| 110 | $unquoted &&= $$unquoted; | ||||
| 111 | if (($deferred && $deferred eq $sub) | ||||
| 112 | || ($unquoted && $unquoted eq $sub)) { | ||||
| 113 | return [ $name, $code, $captured, $unquoted, $deferred ]; | ||||
| 114 | } | ||||
| 115 | return undef; | ||||
| 116 | } | ||||
| 117 | |||||
| 118 | # spent 5.21ms (417µs+4.79) within Sub::Quote::unquote_sub which was called 17 times, avg 306µs/call:
# 10 times (242µs+3.36ms) by Method::Generate::Constructor::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Method/Generate/Constructor.pm:97] at line 95 of Method/Generate/Constructor.pm, avg 360µs/call
# 7 times (175µs+1.43ms) by Sub::Quote::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Sub/Quote.pm:98] at line 97, avg 230µs/call | ||||
| 119 | 17 | 4µs | my ($sub) = @_; | ||
| 120 | 17 | 16µs | my $quoted = $QUOTED{$sub} or return undef; | ||
| 121 | 17 | 8µs | my $unquoted = $quoted->[3]; | ||
| 122 | 17 | 11µs | unless ($unquoted && $$unquoted) { | ||
| 123 | 17 | 12µs | my ($name, $code, $captures) = @$quoted; | ||
| 124 | |||||
| 125 | 17 | 6µs | my $make_sub = "{\n"; | ||
| 126 | |||||
| 127 | 17 | 16µs | my %captures = $captures ? %$captures : (); | ||
| 128 | 17 | 10µs | $captures{'$_UNQUOTED'} = \$unquoted; | ||
| 129 | 17 | 7µs | $captures{'$_QUOTED'} = \$quoted; | ||
| 130 | 17 | 26µs | 17 | 345µs | $make_sub .= capture_unroll("\$_[1]", \%captures, 2); # spent 345µs making 17 calls to Sub::Quote::capture_unroll, avg 20µs/call |
| 131 | |||||
| 132 | 17 | 12µs | $make_sub .= ( | ||
| 133 | $name | ||||
| 134 | # disable the 'variable $x will not stay shared' warning since | ||||
| 135 | # we're not letting it escape from this scope anyway so there's | ||||
| 136 | # nothing trying to share it | ||||
| 137 | ? " no warnings 'closure';\n sub ${name} {\n" | ||||
| 138 | : " \$\$_UNQUOTED = sub {\n" | ||||
| 139 | ); | ||||
| 140 | 17 | 6µs | $make_sub .= " \$_QUOTED if 0;\n"; | ||
| 141 | 17 | 4µs | $make_sub .= " \$_UNQUOTED if 0;\n"; | ||
| 142 | 17 | 9µs | $make_sub .= $code; | ||
| 143 | 17 | 9µs | $make_sub .= " }".($name ? '' : ';')."\n"; | ||
| 144 | 17 | 19µs | if ($name) { | ||
| 145 | $make_sub .= " \$\$_UNQUOTED = \\&${name}\n"; | ||||
| 146 | } | ||||
| 147 | 17 | 3µs | $make_sub .= "}\n1;\n"; | ||
| 148 | 17 | 9µs | $ENV{SUB_QUOTE_DEBUG} && warn $make_sub; | ||
| 149 | { | ||||
| 150 | 19 | 150µs | 2 | 26µs | # spent 16µs (6+10) within Sub::Quote::BEGIN@150 which was called:
# once (6µs+10µs) by Moo::HandleMoose::BEGIN@5 at line 150 # spent 16µs making 1 call to Sub::Quote::BEGIN@150
# spent 10µs making 1 call to strict::unimport |
| 151 | 17 | 42µs | local *{$name} if $name; | ||
| 152 | 17 | 4µs | my ($success, $e); | ||
| 153 | { | ||||
| 154 | 34 | 10µs | local $@; | ||
| 155 | 17 | 24µs | 17 | 4.43ms | $success = _clean_eval($make_sub, \%captures); # spent 4.43ms making 17 calls to Sub::Quote::_clean_eval, avg 261µs/call |
| 156 | 17 | 9µs | $e = $@; | ||
| 157 | } | ||||
| 158 | 17 | 4µs | unless ($success) { | ||
| 159 | die "Eval went very, very wrong:\n\n${make_sub}\n\n$e"; | ||||
| 160 | } | ||||
| 161 | 17 | 73µs | 17 | 18µs | weaken($QUOTED{$$unquoted} = $quoted); # spent 18µs making 17 calls to Scalar::Util::weaken, avg 1µs/call |
| 162 | } | ||||
| 163 | } | ||||
| 164 | 17 | 35µs | $$unquoted; | ||
| 165 | } | ||||
| 166 | |||||
| 167 | sub qsub ($) { | ||||
| 168 | goto "e_sub; | ||||
| 169 | } | ||||
| 170 | |||||
| 171 | sub CLONE { | ||||
| 172 | %QUOTED = map { defined $_ ? ( | ||||
| 173 | $_->[3] && ${$_->[3]} ? (${ $_->[3] } => $_) : (), | ||||
| 174 | $_->[4] ? ($_->[4] => $_) : (), | ||||
| 175 | ) : () } values %QUOTED; | ||||
| 176 | weaken($_) for values %QUOTED; | ||||
| 177 | } | ||||
| 178 | |||||
| 179 | 1 | 3µs | 1; | ||
| 180 | __END__ | ||||
# spent 29µs within Sub::Quote::CORE:match which was called 39 times, avg 751ns/call:
# 39 times (29µs+0s) by Sub::Quote::capture_unroll at line 34, avg 751ns/call |