← Index
NYTProf Performance Profile   « line view »
For t/optimization.t
  Run on Thu Jan 8 22:47:42 2015
Reported on Thu Jan 8 22:48:05 2015

Filename/home/ss5/local/projects/data-dpath/lib/Data/DPath/Path.pm
StatementsExecuted 395 statements in 2.32ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1115.51ms12.0msData::DPath::Path::::BEGIN@11Data::DPath::Path::BEGIN@11
1114.24ms19.4msData::DPath::Path::::BEGIN@7Data::DPath::Path::BEGIN@7
111646µs3.77msData::DPath::Path::::BEGIN@8Data::DPath::Path::BEGIN@8
411448µs1.50msData::DPath::Path::::_build__stepsData::DPath::Path::_build__steps
161192µs103µsData::DPath::Path::::unescapeData::DPath::Path::unescape
41187µs1.58msData::DPath::Path::::newData::DPath::Path::new
463180µs80µsData::DPath::Path::::CORE:matchData::DPath::Path::CORE:match (opcode)
161180µs99µsData::DPath::Path::::quotedData::DPath::Path::quoted
41178µs4.46msData::DPath::Path::::matchData::DPath::Path::match
44126µs4.49msData::DPath::Path::::op_matchData::DPath::Path::op_match
11117µs71µsData::DPath::Path::::BEGIN@4Data::DPath::Path::BEGIN@4
11115µs196µsData::DPath::Path::::BEGIN@14Data::DPath::Path::BEGIN@14
11115µs149µsData::DPath::Path::::BEGIN@21Data::DPath::Path::BEGIN@21
11113µs27µsData::DPath::Path::::BEGIN@115Data::DPath::Path::BEGIN@115
322111µs11µsData::DPath::Path::::CORE:substData::DPath::Path::CORE:subst (opcode)
11111µs16µsData::DPath::Path::::BEGIN@5Data::DPath::Path::BEGIN@5
11111µs46.6msData::DPath::Path::::BEGIN@10Data::DPath::Path::BEGIN@10
1119µs551µsData::DPath::Path::::BEGIN@9Data::DPath::Path::BEGIN@9
1117µs7µsData::DPath::Path::::pathData::DPath::Path::path (xsub)
2222µs2µsData::DPath::Path::::_stepsData::DPath::Path::_steps (xsub)
111700ns700nsData::DPath::Path::::give_referencesData::DPath::Path::give_references (xsub)
0000s0sData::DPath::Path::::unquoteData::DPath::Path::unquote
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Data::DPath::Path;
2# ABSTRACT: Abstraction for a DPath
3
4236µs2124µs
# spent 71µs (17+54) within Data::DPath::Path::BEGIN@4 which was called: # once (17µs+54µs) by Data::DPath::BEGIN@12 at line 4
use strict;
# spent 71µs making 1 call to Data::DPath::Path::BEGIN@4 # spent 54µs making 1 call to strict::import
5225µs222µs
# spent 16µs (11+5) within Data::DPath::Path::BEGIN@5 which was called: # once (11µs+5µs) by Data::DPath::BEGIN@12 at line 5
use warnings;
# spent 16µs making 1 call to Data::DPath::Path::BEGIN@5 # spent 5µs making 1 call to warnings::import
6
72128µs219.5ms
# spent 19.4ms (4.24+15.2) within Data::DPath::Path::BEGIN@7 which was called: # once (4.24ms+15.2ms) by Data::DPath::BEGIN@12 at line 7
use Data::Dumper;
# spent 19.4ms making 1 call to Data::DPath::Path::BEGIN@7 # spent 42µs making 1 call to Exporter::import
82135µs26.84ms
# spent 3.77ms (646µs+3.13) within Data::DPath::Path::BEGIN@8 which was called: # once (646µs+3.13ms) by Data::DPath::BEGIN@12 at line 8
use aliased 'Data::DPath::Step';
# spent 3.77ms making 1 call to Data::DPath::Path::BEGIN@8 # spent 3.07ms making 1 call to aliased::import
9231µs21.09ms
# spent 551µs (9+542) within Data::DPath::Path::BEGIN@9 which was called: # once (9µs+542µs) by Data::DPath::BEGIN@12 at line 9
use aliased 'Data::DPath::Point';
# spent 551µs making 1 call to Data::DPath::Path::BEGIN@9 # spent 542µs making 1 call to aliased::import
10240µs293.1ms
# spent 46.6ms (11µs+46.6) within Data::DPath::Path::BEGIN@10 which was called: # once (11µs+46.6ms) by Data::DPath::BEGIN@12 at line 10
use aliased 'Data::DPath::Context';
# spent 46.6ms making 1 call to Data::DPath::Path::BEGIN@10 # spent 46.6ms making 1 call to aliased::import
113160µs312.1ms
# spent 12.0ms (5.51+6.49) within Data::DPath::Path::BEGIN@11 which was called: # once (5.51ms+6.49ms) by Data::DPath::BEGIN@12 at line 11
use Text::Balanced 2.02 'extract_delimited', 'extract_codeblock';
# spent 12.0ms making 1 call to Data::DPath::Path::BEGIN@11 # spent 74µs making 1 call to Exporter::import # spent 12µs making 1 call to UNIVERSAL::VERSION
12
13use Class::XSAccessor
14111µs1181µs
# spent 196µs (15+181) within Data::DPath::Path::BEGIN@14 which was called: # once (15µs+181µs) by Data::DPath::BEGIN@12 at line 19
chained => 1,
# spent 181µs making 1 call to Class::XSAccessor::import
15 accessors => {
16 path => 'path',
17 _steps => '_steps',
18 give_references => 'give_references',
19145µs1196µs };
# spent 196µs making 1 call to Data::DPath::Path::BEGIN@14
20
21111µs1134µs
# spent 149µs (15+134) within Data::DPath::Path::BEGIN@21 which was called: # once (15µs+134µs) by Data::DPath::BEGIN@12 at line 29
use constant { ROOT => 'ROOT',
# spent 134µs making 1 call to constant::import
22 ANYWHERE => 'ANYWHERE',
23 KEY => 'KEY',
24 ANYSTEP => 'ANYSTEP',
25 NOSTEP => 'NOSTEP',
26 PARENT => 'PARENT',
27 ANCESTOR => 'ANCESTOR',
28 ANCESTOR_OR_SELF => 'ANCESTOR_OR_SELF',
291460µs1149µs };
# spent 149µs making 1 call to Data::DPath::Path::BEGIN@21
30
31
# spent 1.58ms (87µs+1.50) within Data::DPath::Path::new which was called 4 times, avg 396µs/call: # 4 times (87µs+1.50ms) by Data::DPath::__ANON__[lib/Data/DPath.pm:19] at line 18 of lib/Data/DPath.pm, avg 396µs/call
sub new {
3242µs my $class = shift;
33466µs my $self = bless { @_ }, $class;
3446µs41.50ms $self->_build__steps;
# spent 1.50ms making 4 calls to Data::DPath::Path::_build__steps, avg 374µs/call
35411µs return $self;
36}
37
38
# spent 103µs (92+11) within Data::DPath::Path::unescape which was called 16 times, avg 6µs/call: # 16 times (92µs+11µs) by Data::DPath::Path::_build__steps at line 112, avg 6µs/call
sub unescape {
39169µs my ($str) = @_;
40
41164µs return unless defined $str;
421638µs167µs $str =~ s/(?<!\\)\\(["'])/$1/g; # '"$
# spent 7µs making 16 calls to Data::DPath::Path::CORE:subst, avg 444ns/call
431628µs164µs $str =~ s/\\{2}/\\/g;
# spent 4µs making 16 calls to Data::DPath::Path::CORE:subst, avg 250ns/call
441635µs return $str;
45}
46
47sub unquote {
48 my ($str) = @_;
49 $str =~ s/^"(.*)"$/$1/g;
50 return $str;
51}
52
5316119µs1620µs
# spent 99µs (80+20) within Data::DPath::Path::quoted which was called 16 times, avg 6µs/call: # 16 times (80µs+20µs) by Data::DPath::Path::_build__steps at line 77, avg 6µs/call
sub quoted { shift =~ m,^/["'],; } # "
# spent 20µs making 16 calls to Data::DPath::Path::CORE:match, avg 1µs/call
54
55139µseval 'use overload "~~" => \&op_match' if $] >= 5.010;
# spent 40µs executing statements in string eval
# includes 14µs spent executing 1 call to 1 sub defined therein.
56
57
# spent 4.49ms (26µs+4.46) within Data::DPath::Path::op_match which was called 4 times, avg 1.12ms/call: # once (8µs+2.22ms) by main::RUNTIME at line 73 of t/optimization.t # once (5µs+1.92ms) by main::RUNTIME at line 39 of t/optimization.t # once (7µs+217µs) by main::RUNTIME at line 36 of t/optimization.t # once (6µs+99µs) by main::RUNTIME at line 70 of t/optimization.t
sub op_match {
5844µs my ($self, $data, $rhs) = @_;
59
60424µs44.46ms return [ $self->match( $data ) ];
# spent 4.46ms making 4 calls to Data::DPath::Path::match, avg 1.12ms/call
61}
62
63# essentially the Path parser
64
# spent 1.50ms (448µs+1.05) within Data::DPath::Path::_build__steps which was called 4 times, avg 374µs/call: # 4 times (448µs+1.05ms) by Data::DPath::Path::new at line 34, avg 374µs/call
sub _build__steps {
6543µs my ($self) = @_;
66
67421µs17µs my $remaining_path = $self->path;
# spent 7µs making 1 call to Data::DPath::Path::path
684800ns my $extracted;
6941µs my @steps;
70
71456µs314µs push @steps, Step->new->part('')->kind(ROOT);
# spent 9µs making 1 call to Data::DPath::Step::new # spent 4µs making 1 call to Data::DPath::Step::part # spent 900ns making 1 call to Data::DPath::Step::kind
72
7342µs while ($remaining_path) {
74163µs my $plain_part;
75162µs my $filter;
76162µs my $kind;
771626µs1699µs if ( quoted($remaining_path) ) {
# spent 99µs making 16 calls to Data::DPath::Path::quoted, avg 6µs/call
78 ($plain_part, $remaining_path) = extract_delimited($remaining_path, q/'"/, "/"); # '
79 ($filter, $remaining_path) = extract_codeblock($remaining_path, "[]");
80 $plain_part = unescape unquote $plain_part;
81 $kind = KEY; # quoted is always a key
82 }
83 else
84 {
85165µs my $filter_already_extracted = 0;
861644µs16760µs ($extracted, $remaining_path) = extract_delimited($remaining_path,'/');
# spent 760µs making 16 calls to Text::Balanced::extract_delimited, avg 47µs/call
87
881611µs if (not $extracted) {
89 ($extracted, $remaining_path) = ($remaining_path, undef); # END OF PATH
90 } else {
91
92 # work around to recognize slashes in filter expressions and handle them:
93 #
94 # - 1) see if key unexpectedly contains opening "[" but no closing "]"
95 # - 2) use the part before "["
96 # - 3) unshift the rest to remaining
97 # - 4) extract_codeblock() explicitely
981250µs1418µs if ($extracted =~ /(.*)((?<!\\)\[.*)/ and $extracted !~ m|\]/\s*$|) {
# spent 18µs making 14 calls to Data::DPath::Path::CORE:match, avg 1µs/call
99 $remaining_path = $2 . $remaining_path;
100 ( $plain_part = $1 ) =~ s|^/||;
101 ($filter, $remaining_path) = extract_codeblock($remaining_path, "[]");
102 $filter_already_extracted = 1;
103 } else {
1041213µs $remaining_path = (chop $extracted) . $remaining_path;
105 }
106 }
107
1081691µs1642µs ($plain_part, $filter) = $extracted =~ m,^/ # leading /
# spent 42µs making 16 calls to Data::DPath::Path::CORE:match, avg 3µs/call
109 (.*?) # path part
110 (\[.*\])?$ # optional filter
111 ,xg unless $filter_already_extracted;
1121628µs16103µs $plain_part = unescape $plain_part;
# spent 103µs making 16 calls to Data::DPath::Path::unescape, avg 6µs/call
113 }
114
1152250µs241µs
# spent 27µs (13+14) within Data::DPath::Path::BEGIN@115 which was called: # once (13µs+14µs) by Data::DPath::BEGIN@12 at line 115
no warnings 'uninitialized';
# spent 27µs making 1 call to Data::DPath::Path::BEGIN@115 # spent 14µs making 1 call to warnings::unimport
1161616µs if ($plain_part eq '') { $kind ||= ANYWHERE }
117 elsif ($plain_part eq '*') { $kind ||= ANYSTEP }
118 elsif ($plain_part eq '.') { $kind ||= NOSTEP }
119 elsif ($plain_part eq '..') { $kind ||= PARENT }
120 elsif ($plain_part eq '::ancestor') { $kind ||= ANCESTOR }
121 elsif ($plain_part eq '::ancestor-or-self') { $kind ||= ANCESTOR_OR_SELF }
12283µs else { $kind ||= KEY }
123
1241696µs44µs push @steps, Step->new->part($plain_part)->kind($kind)->filter($filter);
# spent 2µs making 1 call to Data::DPath::Step::new # spent 1µs making 1 call to Data::DPath::Step::part # spent 700ns making 1 call to Data::DPath::Step::filter # spent 700ns making 1 call to Data::DPath::Step::kind
125 }
12648µs12µs pop @steps if $steps[-1]->kind eq ANYWHERE; # ignore final '/'
# spent 2µs making 1 call to Data::DPath::Step::kind
127420µs11µs $self->_steps( \@steps );
# spent 1µs making 1 call to Data::DPath::Path::_steps
128}
129
130
# spent 4.46ms (78µs+4.38) within Data::DPath::Path::match which was called 4 times, avg 1.12ms/call: # 4 times (78µs+4.38ms) by Data::DPath::Path::op_match at line 60, avg 1.12ms/call
sub match {
13143µs my ($self, $data) = @_;
132
133474µs614µs my $context = Context
# spent 6µs making 1 call to Data::DPath::Point::new # spent 5µs making 1 call to Data::DPath::Context::new # spent 1µs making 1 call to Data::DPath::Point::ref # spent 800ns making 1 call to Data::DPath::Context::current_points # spent 700ns making 1 call to Data::DPath::Path::give_references # spent 600ns making 1 call to Data::DPath::Context::give_references
134 ->new
135 ->current_points([ Point->new->ref(\$data) ])
136 ->give_references($self->give_references);
137417µs44.37ms return $context->match($self);
# spent 4.37ms making 4 calls to Data::DPath::Context::match, avg 1.09ms/call
138}
139
14014µs1;
141
142__END__
 
# spent 80µs within Data::DPath::Path::CORE:match which was called 46 times, avg 2µs/call: # 16 times (42µs+0s) by Data::DPath::Path::_build__steps at line 108, avg 3µs/call # 16 times (20µs+0s) by Data::DPath::Path::quoted at line 53, avg 1µs/call # 14 times (18µs+0s) by Data::DPath::Path::_build__steps at line 98, avg 1µs/call
sub Data::DPath::Path::CORE:match; # opcode
# spent 11µs within Data::DPath::Path::CORE:subst which was called 32 times, avg 347ns/call: # 16 times (7µs+0s) by Data::DPath::Path::unescape at line 42, avg 444ns/call # 16 times (4µs+0s) by Data::DPath::Path::unescape at line 43, avg 250ns/call
sub Data::DPath::Path::CORE:subst; # opcode
# spent 2µs within Data::DPath::Path::_steps which was called 2 times, avg 900ns/call: # once (1µs+0s) by Data::DPath::Path::_build__steps at line 127 # once (700ns+0s) by Data::DPath::Context::_search at line 418 of lib/Data/DPath/Context.pm
sub Data::DPath::Path::_steps; # xsub
# spent 700ns within Data::DPath::Path::give_references which was called: # once (700ns+0s) by Data::DPath::Path::match at line 133
sub Data::DPath::Path::give_references; # xsub
# spent 7µs within Data::DPath::Path::path which was called: # once (7µs+0s) by Data::DPath::Path::_build__steps at line 67
sub Data::DPath::Path::path; # xsub