| Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath/Path.pm |
| Statements | Executed 426 statements in 2.16ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 3.74ms | 8.17ms | Data::DPath::Path::BEGIN@17 |
| 1 | 1 | 1 | 3.04ms | 3.45ms | Data::DPath::Path::BEGIN@13 |
| 6 | 1 | 1 | 574µs | 2.42ms | Data::DPath::Path::_build__steps |
| 1 | 1 | 1 | 425µs | 2.68ms | Data::DPath::Path::BEGIN@14 |
| 17 | 2 | 1 | 119µs | 132µs | Data::DPath::Path::unescape |
| 6 | 3 | 2 | 102µs | 2.52ms | Data::DPath::Path::new |
| 17 | 1 | 1 | 97µs | 121µs | Data::DPath::Path::quoted |
| 33 | 3 | 1 | 67µs | 67µs | Data::DPath::Path::CORE:match (opcode) |
| 6 | 1 | 1 | 61µs | 90µs | Data::DPath::Path::unquote |
| 2 | 1 | 1 | 59µs | 640µs | Data::DPath::Path::match |
| 40 | 3 | 1 | 28µs | 28µs | Data::DPath::Path::CORE:subst (opcode) |
| 12 | 1 | 1 | 13µs | 13µs | Data::DPath::Path::CORE:substcont (opcode) |
| 1 | 1 | 1 | 12µs | 115µs | Data::DPath::Path::BEGIN@27 |
| 1 | 1 | 1 | 11µs | 136µs | Data::DPath::Path::BEGIN@20 |
| 1 | 1 | 1 | 10µs | 23µs | Data::DPath::Path::BEGIN@121 |
| 1 | 1 | 1 | 8µs | 18µs | Data::DPath::Path::BEGIN@10 |
| 1 | 1 | 1 | 7µs | 31.3ms | Data::DPath::Path::BEGIN@16 |
| 1 | 1 | 1 | 7µs | 10µs | Data::DPath::Path::BEGIN@11 |
| 1 | 1 | 1 | 6µs | 381µs | Data::DPath::Path::BEGIN@15 |
| 1 | 1 | 1 | 6µs | 6µs | Data::DPath::Path::BEGIN@2 |
| 2 | 2 | 2 | 5µs | 5µs | Data::DPath::Path::_steps (xsub) |
| 1 | 1 | 1 | 2µs | 2µs | Data::DPath::Path::path (xsub) |
| 1 | 1 | 1 | 1µs | 1µs | Data::DPath::Path::give_references (xsub) |
| 0 | 0 | 0 | 0s | 0s | Data::DPath::Path::op_match |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Data::DPath::Path; | ||||
| 2 | # spent 6µs within Data::DPath::Path::BEGIN@2 which was called:
# once (6µs+0s) by Data::DPath::BEGIN@20 at line 4 | ||||
| 3 | 1 | 4µs | $Data::DPath::Path::AUTHORITY = 'cpan:SCHWIGON'; | ||
| 4 | 1 | 19µs | 1 | 6µs | } # spent 6µs making 1 call to Data::DPath::Path::BEGIN@2 |
| 5 | { | ||||
| 6 | 2 | 800ns | $Data::DPath::Path::VERSION = '0.49'; | ||
| 7 | } | ||||
| 8 | # ABSTRACT: Abstraction for a DPath | ||||
| 9 | |||||
| 10 | 2 | 17µs | 2 | 27µs | # spent 18µs (8+9) within Data::DPath::Path::BEGIN@10 which was called:
# once (8µs+9µs) by Data::DPath::BEGIN@20 at line 10 # spent 18µs making 1 call to Data::DPath::Path::BEGIN@10
# spent 9µs making 1 call to strict::import |
| 11 | 2 | 18µs | 2 | 13µs | # spent 10µs (7+3) within Data::DPath::Path::BEGIN@11 which was called:
# once (7µs+3µs) by Data::DPath::BEGIN@20 at line 11 # spent 10µs making 1 call to Data::DPath::Path::BEGIN@11
# spent 3µs making 1 call to warnings::import |
| 12 | |||||
| 13 | 2 | 84µs | 2 | 3.48ms | # spent 3.45ms (3.04+416µs) within Data::DPath::Path::BEGIN@13 which was called:
# once (3.04ms+416µs) by Data::DPath::BEGIN@20 at line 13 # spent 3.45ms making 1 call to Data::DPath::Path::BEGIN@13
# spent 25µs making 1 call to Exporter::import |
| 14 | 2 | 88µs | 2 | 4.89ms | # spent 2.68ms (425µs+2.26) within Data::DPath::Path::BEGIN@14 which was called:
# once (425µs+2.26ms) by Data::DPath::BEGIN@20 at line 14 # spent 2.68ms making 1 call to Data::DPath::Path::BEGIN@14
# spent 2.21ms making 1 call to aliased::import |
| 15 | 2 | 20µs | 2 | 755µs | # spent 381µs (6+374) within Data::DPath::Path::BEGIN@15 which was called:
# once (6µs+374µs) by Data::DPath::BEGIN@20 at line 15 # spent 381µs making 1 call to Data::DPath::Path::BEGIN@15
# spent 374µs making 1 call to aliased::import |
| 16 | 2 | 32µs | 2 | 62.6ms | # spent 31.3ms (7µs+31.3) within Data::DPath::Path::BEGIN@16 which was called:
# once (7µs+31.3ms) by Data::DPath::BEGIN@20 at line 16 # spent 31.3ms making 1 call to Data::DPath::Path::BEGIN@16
# spent 31.3ms making 1 call to aliased::import |
| 17 | 3 | 125µs | 3 | 8.23ms | # spent 8.17ms (3.74+4.43) within Data::DPath::Path::BEGIN@17 which was called:
# once (3.74ms+4.43ms) by Data::DPath::BEGIN@20 at line 17 # spent 8.17ms making 1 call to Data::DPath::Path::BEGIN@17
# spent 50µs making 1 call to Exporter::import
# spent 11µs making 1 call to UNIVERSAL::VERSION |
| 18 | |||||
| 19 | use Class::XSAccessor | ||||
| 20 | 1 | 8µs | 1 | 125µs | # spent 136µs (11+125) within Data::DPath::Path::BEGIN@20 which was called:
# once (11µs+125µs) by Data::DPath::BEGIN@20 at line 25 # spent 125µs making 1 call to Class::XSAccessor::import |
| 21 | accessors => { | ||||
| 22 | path => 'path', | ||||
| 23 | _steps => '_steps', | ||||
| 24 | give_references => 'give_references', | ||||
| 25 | 1 | 31µs | 1 | 136µs | }; # spent 136µs making 1 call to Data::DPath::Path::BEGIN@20 |
| 26 | |||||
| 27 | 1 | 10µs | 1 | 103µs | # spent 115µs (12+103) within Data::DPath::Path::BEGIN@27 which was called:
# once (12µs+103µs) by Data::DPath::BEGIN@20 at line 35 # spent 103µs making 1 call to constant::import |
| 28 | ANYWHERE => 'ANYWHERE', | ||||
| 29 | KEY => 'KEY', | ||||
| 30 | ANYSTEP => 'ANYSTEP', | ||||
| 31 | NOSTEP => 'NOSTEP', | ||||
| 32 | PARENT => 'PARENT', | ||||
| 33 | ANCESTOR => 'ANCESTOR', | ||||
| 34 | ANCESTOR_OR_SELF => 'ANCESTOR_OR_SELF', | ||||
| 35 | 1 | 350µs | 1 | 115µs | }; # spent 115µs making 1 call to Data::DPath::Path::BEGIN@27 |
| 36 | |||||
| 37 | # spent 2.52ms (102µs+2.42) within Data::DPath::Path::new which was called 6 times, avg 420µs/call:
# 3 times (23µs+458µs) by Data::DPath::Context::isearch at line 417 of Data/DPath/Context.pm, avg 160µs/call
# 2 times (16µs+1.61ms) by Data::DPath::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath.pm:27] at line 26 of Data/DPath.pm, avg 813µs/call
# once (62µs+348µs) by Data::DPath::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath.pm:47] at line 41 of Data/DPath.pm | ||||
| 38 | 6 | 4µs | my $class = shift; | ||
| 39 | 6 | 62µs | my $self = bless { @_ }, $class; | ||
| 40 | 6 | 15µs | 6 | 2.42ms | $self->_build__steps; # spent 2.42ms making 6 calls to Data::DPath::Path::_build__steps, avg 403µs/call |
| 41 | 6 | 26µs | return $self; | ||
| 42 | } | ||||
| 43 | |||||
| 44 | sub unescape { | ||||
| 45 | 17 | 9µs | my ($str) = @_; | ||
| 46 | |||||
| 47 | 17 | 3µs | return unless defined $str; | ||
| 48 | 17 | 50µs | 17 | 7µs | $str =~ s/(?<!\\)\\(["'])/$1/g; # '"$ # spent 7µs making 17 calls to Data::DPath::Path::CORE:subst, avg 435ns/call |
| 49 | 17 | 38µs | 17 | 5µs | $str =~ s/\\{2}/\\/g; # spent 5µs making 17 calls to Data::DPath::Path::CORE:subst, avg 306ns/call |
| 50 | 17 | 50µs | return $str; | ||
| 51 | } | ||||
| 52 | |||||
| 53 | # spent 90µs (61+29) within Data::DPath::Path::unquote which was called 6 times, avg 15µs/call:
# 6 times (61µs+29µs) by Data::DPath::Path::_build__steps at line 86, avg 15µs/call | ||||
| 54 | 6 | 3µs | my ($str) = @_; | ||
| 55 | 6 | 75µs | 18 | 29µs | $str =~ s/^"(.*)"$/$1/g; # spent 16µs making 6 calls to Data::DPath::Path::CORE:subst, avg 3µs/call
# spent 13µs making 12 calls to Data::DPath::Path::CORE:substcont, avg 1µs/call |
| 56 | 6 | 20µs | return $str; | ||
| 57 | } | ||||
| 58 | |||||
| 59 | 17 | 144µs | 17 | 24µs | # spent 121µs (97+24) within Data::DPath::Path::quoted which was called 17 times, avg 7µs/call:
# 17 times (97µs+24µs) by Data::DPath::Path::_build__steps at line 83, avg 7µs/call # spent 24µs making 17 calls to Data::DPath::Path::CORE:match, avg 1µs/call |
| 60 | |||||
| 61 | 1 | 39µs | eval 'use overload "~~" => \&op_match' if $] >= 5.010; # spent 12µs executing statements in string eval # includes 10µs spent executing 1 call to 1 sub defined therein. | ||
| 62 | |||||
| 63 | sub op_match { | ||||
| 64 | my ($self, $data, $rhs) = @_; | ||||
| 65 | |||||
| 66 | return [ $self->match( $data ) ]; | ||||
| 67 | } | ||||
| 68 | |||||
| 69 | # essentially the Path parser | ||||
| 70 | # spent 2.42ms (574µs+1.84) within Data::DPath::Path::_build__steps which was called 6 times, avg 403µs/call:
# 6 times (574µs+1.84ms) by Data::DPath::Path::new at line 40, avg 403µs/call | ||||
| 71 | 6 | 4µs | my ($self) = @_; | ||
| 72 | |||||
| 73 | 6 | 21µs | 1 | 2µs | my $remaining_path = $self->path; # spent 2µs making 1 call to Data::DPath::Path::path |
| 74 | 6 | 800ns | my $extracted; | ||
| 75 | 6 | 2µs | my @steps; | ||
| 76 | |||||
| 77 | 6 | 66µs | 3 | 13µs | push @steps, Step->new->part('')->kind(ROOT); # spent 9µs making 1 call to Data::DPath::Step::new
# spent 2µs making 1 call to Data::DPath::Step::kind
# spent 1µs making 1 call to Data::DPath::Step::part |
| 78 | |||||
| 79 | 6 | 4µs | while ($remaining_path) { | ||
| 80 | 17 | 2µs | my $plain_part; | ||
| 81 | 17 | 2µs | my $filter; | ||
| 82 | 17 | 2µs | my $kind; | ||
| 83 | 17 | 31µs | 17 | 121µs | if ( quoted($remaining_path) ) { # spent 121µs making 17 calls to Data::DPath::Path::quoted, avg 7µs/call |
| 84 | 6 | 20µs | 6 | 347µs | ($plain_part, $remaining_path) = extract_delimited($remaining_path, q/'"/, "/"); # ' # spent 347µs making 6 calls to Text::Balanced::extract_delimited, avg 58µs/call |
| 85 | 6 | 22µs | 6 | 377µs | ($filter, $remaining_path) = extract_codeblock($remaining_path, "[]"); # spent 377µs making 6 calls to Text::Balanced::extract_codeblock, avg 63µs/call |
| 86 | 6 | 19µs | 12 | 131µs | $plain_part = unescape unquote $plain_part; # spent 90µs making 6 calls to Data::DPath::Path::unquote, avg 15µs/call
# spent 41µs making 6 calls to Data::DPath::Path::unescape, avg 7µs/call |
| 87 | 6 | 3µs | $kind = KEY; # quoted is always a key | ||
| 88 | } | ||||
| 89 | else | ||||
| 90 | { | ||||
| 91 | 11 | 4µs | my $filter_already_extracted = 0; | ||
| 92 | 11 | 38µs | 11 | 705µs | ($extracted, $remaining_path) = extract_delimited($remaining_path,'/'); # spent 705µs making 11 calls to Text::Balanced::extract_delimited, avg 64µs/call |
| 93 | |||||
| 94 | 11 | 10µs | if (not $extracted) { | ||
| 95 | ($extracted, $remaining_path) = ($remaining_path, undef); # END OF PATH | ||||
| 96 | } else { | ||||
| 97 | |||||
| 98 | # work around to recognize slashes in filter expressions and handle them: | ||||
| 99 | # | ||||
| 100 | # - 1) see if key unexpectedly contains opening "[" but no closing "]" | ||||
| 101 | # - 2) use the part before "[" | ||||
| 102 | # - 3) unshift the rest to remaining | ||||
| 103 | # - 4) extract_codeblock() explicitely | ||||
| 104 | 5 | 20µs | 5 | 4µs | if ($extracted =~ /(.*)((?<!\\)\[.*)/ and $extracted !~ m|\]/\s*$|) { # spent 4µs making 5 calls to Data::DPath::Path::CORE:match, avg 760ns/call |
| 105 | $remaining_path = $2 . $remaining_path; | ||||
| 106 | ( $plain_part = $1 ) =~ s|^/||; | ||||
| 107 | ($filter, $remaining_path) = extract_codeblock($remaining_path, "[]"); | ||||
| 108 | $filter_already_extracted = 1; | ||||
| 109 | } else { | ||||
| 110 | 5 | 8µs | $remaining_path = (chop $extracted) . $remaining_path; | ||
| 111 | } | ||||
| 112 | } | ||||
| 113 | |||||
| 114 | 11 | 81µs | 11 | 39µs | ($plain_part, $filter) = $extracted =~ m,^/ # leading / # spent 39µs making 11 calls to Data::DPath::Path::CORE:match, avg 4µs/call |
| 115 | (.*?) # path part | ||||
| 116 | (\[.*\])?$ # optional filter | ||||
| 117 | ,xg unless $filter_already_extracted; | ||||
| 118 | 11 | 24µs | 11 | 91µs | $plain_part = unescape $plain_part; # spent 91µs making 11 calls to Data::DPath::Path::unescape, avg 8µs/call |
| 119 | } | ||||
| 120 | |||||
| 121 | 2 | 171µs | 2 | 36µs | # spent 23µs (10+13) within Data::DPath::Path::BEGIN@121 which was called:
# once (10µs+13µs) by Data::DPath::BEGIN@20 at line 121 # spent 23µs making 1 call to Data::DPath::Path::BEGIN@121
# spent 13µs making 1 call to warnings::unimport |
| 122 | 17 | 17µs | if ($plain_part eq '') { $kind ||= ANYWHERE } | ||
| 123 | elsif ($plain_part eq '*') { $kind ||= ANYSTEP } | ||||
| 124 | elsif ($plain_part eq '.') { $kind ||= NOSTEP } | ||||
| 125 | elsif ($plain_part eq '..') { $kind ||= PARENT } | ||||
| 126 | elsif ($plain_part eq '::ancestor') { $kind ||= ANCESTOR } | ||||
| 127 | elsif ($plain_part eq '::ancestor-or-self') { $kind ||= ANCESTOR_OR_SELF } | ||||
| 128 | 11 | 4µs | else { $kind ||= KEY } | ||
| 129 | |||||
| 130 | 17 | 120µs | 4 | 8µs | push @steps, Step->new->part($plain_part)->kind($kind)->filter($filter); # spent 3µs making 1 call to Data::DPath::Step::new
# spent 2µs making 1 call to Data::DPath::Step::kind
# spent 1µs making 1 call to Data::DPath::Step::part
# spent 1µs making 1 call to Data::DPath::Step::filter |
| 131 | } | ||||
| 132 | 6 | 13µs | 1 | 2µs | pop @steps if $steps[-1]->kind eq ANYWHERE; # ignore final '/' # spent 2µs making 1 call to Data::DPath::Step::kind |
| 133 | 6 | 38µs | 1 | 4µs | $self->_steps( \@steps ); # spent 4µs making 1 call to Data::DPath::Path::_steps |
| 134 | } | ||||
| 135 | |||||
| 136 | # spent 640µs (59+581) within Data::DPath::Path::match which was called 2 times, avg 320µs/call:
# 2 times (59µs+581µs) by Benchmark::Perl::Formance::print_outstyle_summary at line 725 of lib/Benchmark/Perl/Formance.pm, avg 320µs/call | ||||
| 137 | 2 | 2µs | my ($self, $data) = @_; | ||
| 138 | |||||
| 139 | 2 | 52µs | 6 | 9µs | my $context = Context # spent 2µs making 1 call to Data::DPath::Context::new
# spent 2µs making 1 call to Data::DPath::Point::new
# spent 1µs making 1 call to Data::DPath::Path::give_references
# spent 1µs making 1 call to Data::DPath::Context::current_points
# spent 1µs making 1 call to Data::DPath::Point::ref
# spent 700ns making 1 call to Data::DPath::Context::give_references |
| 140 | ->new | ||||
| 141 | ->current_points([ Point->new->ref(\$data) ]) | ||||
| 142 | ->give_references($self->give_references); | ||||
| 143 | 2 | 12µs | 2 | 572µs | return $context->match($self); # spent 572µs making 2 calls to Data::DPath::Context::match, avg 286µs/call |
| 144 | } | ||||
| 145 | |||||
| 146 | 1 | 2µs | 1; | ||
| 147 | |||||
| 148 | __END__ | ||||
# spent 67µs within Data::DPath::Path::CORE:match which was called 33 times, avg 2µs/call:
# 17 times (24µs+0s) by Data::DPath::Path::quoted at line 59, avg 1µs/call
# 11 times (39µs+0s) by Data::DPath::Path::_build__steps at line 114, avg 4µs/call
# 5 times (4µs+0s) by Data::DPath::Path::_build__steps at line 104, avg 760ns/call | |||||
# spent 28µs within Data::DPath::Path::CORE:subst which was called 40 times, avg 705ns/call:
# 17 times (7µs+0s) by Data::DPath::Path::unescape at line 48, avg 435ns/call
# 17 times (5µs+0s) by Data::DPath::Path::unescape at line 49, avg 306ns/call
# 6 times (16µs+0s) by Data::DPath::Path::unquote at line 55, avg 3µs/call | |||||
# spent 13µs within Data::DPath::Path::CORE:substcont which was called 12 times, avg 1µs/call:
# 12 times (13µs+0s) by Data::DPath::Path::unquote at line 55, avg 1µs/call | |||||
# spent 5µs within Data::DPath::Path::_steps which was called 2 times, avg 2µs/call:
# once (4µs+0s) by Data::DPath::Path::_build__steps at line 133
# once (900ns+0s) by Data::DPath::Context::_search at line 428 of Data/DPath/Context.pm | |||||
# spent 1µs within Data::DPath::Path::give_references which was called:
# once (1µs+0s) by Data::DPath::Path::match at line 139 | |||||
# spent 2µs within Data::DPath::Path::path which was called:
# once (2µs+0s) by Data::DPath::Path::_build__steps at line 73 |