← Index
NYTProf Performance Profile   « line view »
For bin/benchmark-perlformance
  Run on Fri Apr 17 15:31:48 2015
Reported on Fri Apr 17 15:32:02 2015

Filename/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath/Context.pm
StatementsExecuted 973 statements in 4.69ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1112.38ms5.71msData::DPath::Context::::BEGIN@22Data::DPath::Context::BEGIN@22
1111.65ms10.1msData::DPath::Context::::BEGIN@23Data::DPath::Context::BEGIN@23
1111.08ms9.60msData::DPath::Context::::BEGIN@19Data::DPath::Context::BEGIN@19
821543µs591µsData::DPath::Context::::_anyData::DPath::Context::_any (recurses: max depth 7, inclusive time 2.03ms)
111459µs664µsData::DPath::Context::::BEGIN@18Data::DPath::Context::BEGIN@18
1111362µs425µsData::DPath::Context::::_select_keyData::DPath::Context::_select_key
111344µs721µsData::DPath::Context::::BEGIN@16Data::DPath::Context::BEGIN@16
632231µs1.59msData::DPath::Context::::_searchData::DPath::Context::_search
111224µs288µsData::DPath::Context::::BEGIN@17Data::DPath::Context::BEGIN@17
2951117µs146µsData::DPath::Context::::_filter_pointsData::DPath::Context::_filter_points
211101µs184µsData::DPath::Context::::_select_anystepData::DPath::Context::_select_anystep
131175µs79µsData::DPath::Context::::__ANON__[:411]Data::DPath::Context::__ANON__[:411]
42249µs1.61msData::DPath::Context::::_iterData::DPath::Context::_iter
32145µs1.92msData::DPath::Context::::isearchData::DPath::Context::isearch
61143µs65µsData::DPath::Context::::_select_rootData::DPath::Context::_select_root
21140µs46µsData::DPath::Context::::_select_ancestorData::DPath::Context::_select_ancestor
11134µs631µsData::DPath::Context::::_select_anywhereData::DPath::Context::_select_anywhere
21134µs54µsData::DPath::Context::::_allData::DPath::Context::_all
33328µs28µsData::DPath::Context::::newData::DPath::Context::new (xsub)
101128µs29µsData::DPath::Context::::first_pointData::DPath::Context::first_point
11119µs225µsData::DPath::Context::::BEGIN@64Data::DPath::Context::BEGIN@64
21119µs572µsData::DPath::Context::::matchData::DPath::Context::match
11117µs680µsData::DPath::Context::::BEGIN@29Data::DPath::Context::BEGIN@29
11116µs34µsData::DPath::Context::::BEGIN@102Data::DPath::Context::BEGIN@102
11115µs184µsData::DPath::Context::::BEGIN@57Data::DPath::Context::BEGIN@57
88314µs14µsData::DPath::Context::::current_pointsData::DPath::Context::current_points (xsub)
11114µs32µsData::DPath::Context::::BEGIN@158Data::DPath::Context::BEGIN@158
11113µs36µsData::DPath::Filters::::BEGIN@204Data::DPath::Filters::BEGIN@204
11112µs24µsData::DPath::Context::::BEGIN@159Data::DPath::Context::BEGIN@159
11112µs41µsData::DPath::Context::::BEGIN@20Data::DPath::Context::BEGIN@20
11110µs16µsData::DPath::Context::::BEGIN@425Data::DPath::Context::BEGIN@425
1119µs12µsData::DPath::Context::::BEGIN@11Data::DPath::Context::BEGIN@11
2119µs9µsData::DPath::Context::::_filter_points_indexData::DPath::Context::_filter_points_index
1119µs16µsData::DPath::Context::::BEGIN@281Data::DPath::Context::BEGIN@281
1118µs15µsData::DPath::Context::::BEGIN@305Data::DPath::Context::BEGIN@305
2118µs8µsData::DPath::Context::::CORE:substData::DPath::Context::CORE:subst (opcode)
1118µs15µsData::DPath::Context::::BEGIN@223Data::DPath::Context::BEGIN@223
1118µs17µsData::DPath::Context::::BEGIN@222Data::DPath::Context::BEGIN@222
1117µs27µsData::DPath::Context::::BEGIN@13Data::DPath::Context::BEGIN@13
1117µs17µsData::DPath::Context::::BEGIN@424Data::DPath::Context::BEGIN@424
1116µs70µsData::DPath::Context::::BEGIN@14Data::DPath::Context::BEGIN@14
1116µs6µsData::DPath::Context::::BEGIN@2Data::DPath::Context::BEGIN@2
1116µs310µsData::DPath::Context::::BEGIN@15Data::DPath::Context::BEGIN@15
1116µs16µsData::DPath::Context::::BEGIN@10Data::DPath::Context::BEGIN@10
2115µs5µsData::DPath::Context::::CORE:matchData::DPath::Context::CORE:match (opcode)
4114µs4µsData::DPath::Context::::CORE:substcontData::DPath::Context::CORE:substcont (opcode)
1114µs4µsData::DPath::Filters::::BEGIN@33Data::DPath::Filters::BEGIN@33
2222µs2µsData::DPath::Context::::give_referencesData::DPath::Context::give_references (xsub)
0000s0sData::DPath::Context::::_filter_points_evalData::DPath::Context::_filter_points_eval
0000s0sData::DPath::Context::::_select_ancestor_or_selfData::DPath::Context::_select_ancestor_or_self
0000s0sData::DPath::Context::::_select_nostepData::DPath::Context::_select_nostep
0000s0sData::DPath::Context::::_select_parentData::DPath::Context::_select_parent
0000s0sData::DPath::Context::::_splice_threadsData::DPath::Context::_splice_threads
0000s0sData::DPath::Context::::all_pointsData::DPath::Context::all_points
0000s0sData::DPath::Context::::derefData::DPath::Context::deref
0000s0sData::DPath::Context::::refData::DPath::Context::ref
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::Context;
2
# spent 6µs within Data::DPath::Context::BEGIN@2 which was called: # once (6µs+0s) by Data::DPath::Path::BEGIN@1.2 at line 4
BEGIN {
315µs $Data::DPath::Context::AUTHORITY = 'cpan:SCHWIGON';
4120µs16µs}
# spent 6µs making 1 call to Data::DPath::Context::BEGIN@2
5{
62900ns $Data::DPath::Context::VERSION = '0.49';
7}
8# ABSTRACT: Abstraction for a current context that enables incremental searches
9
10216µs225µs
# spent 16µs (6+10) within Data::DPath::Context::BEGIN@10 which was called: # once (6µs+10µs) by Data::DPath::Path::BEGIN@1.2 at line 10
use strict;
# spent 16µs making 1 call to Data::DPath::Context::BEGIN@10 # spent 10µs making 1 call to strict::import
11232µs215µs
# spent 12µs (9+3) within Data::DPath::Context::BEGIN@11 which was called: # once (9µs+3µs) by Data::DPath::Path::BEGIN@1.2 at line 11
use warnings;
# spent 12µs making 1 call to Data::DPath::Context::BEGIN@11 # spent 3µs making 1 call to warnings::import
12
13219µs246µs
# spent 27µs (7+19) within Data::DPath::Context::BEGIN@13 which was called: # once (7µs+19µs) by Data::DPath::Path::BEGIN@1.2 at line 13
use Data::Dumper;
# spent 27µs making 1 call to Data::DPath::Context::BEGIN@13 # spent 19µs making 1 call to Exporter::import
14220µs270µs
# spent 70µs (6+63) within Data::DPath::Context::BEGIN@14 which was called: # once (6µs+63µs) by Data::DPath::Path::BEGIN@1.2 at line 14
use aliased 'Data::DPath::Point';
# spent 70µs making 1 call to Data::DPath::Context::BEGIN@14 # spent 63µs making 1 call to aliased::import, recursion: max depth 1, sum of overlapping time 63µs
15220µs2310µs
# spent 310µs (6+304) within Data::DPath::Context::BEGIN@15 which was called: # once (6µs+304µs) by Data::DPath::Path::BEGIN@1.2 at line 15
use aliased 'Data::DPath::Attrs';
# spent 310µs making 1 call to Data::DPath::Context::BEGIN@15 # spent 304µs making 1 call to aliased::import, recursion: max depth 1, sum of overlapping time 304µs
16272µs2790µs
# spent 721µs (344+377) within Data::DPath::Context::BEGIN@16 which was called: # once (344µs+377µs) by Data::DPath::Path::BEGIN@1.2 at line 16
use List::MoreUtils 'uniq';
# spent 721µs making 1 call to Data::DPath::Context::BEGIN@16 # spent 69µs making 1 call to Exporter::import
17269µs2332µs
# spent 288µs (224+63) within Data::DPath::Context::BEGIN@17 which was called: # once (224µs+63µs) by Data::DPath::Path::BEGIN@1.2 at line 17
use Scalar::Util 'reftype';
# spent 288µs making 1 call to Data::DPath::Context::BEGIN@17 # spent 44µs making 1 call to Exporter::import
18277µs1664µs
# spent 664µs (459+205) within Data::DPath::Context::BEGIN@18 which was called: # once (459µs+205µs) by Data::DPath::Path::BEGIN@1.2 at line 18
use Data::DPath::Filters;
# spent 664µs making 1 call to Data::DPath::Context::BEGIN@18
19276µs29.65ms
# spent 9.60ms (1.08+8.52) within Data::DPath::Context::BEGIN@19 which was called: # once (1.08ms+8.52ms) by Data::DPath::Path::BEGIN@1.2 at line 19
use Iterator::Util;
# spent 9.60ms making 1 call to Data::DPath::Context::BEGIN@19 # spent 55µs making 1 call to Exporter::import
20221µs249µs
# spent 41µs (12+29) within Data::DPath::Context::BEGIN@20 which was called: # once (12µs+29µs) by Data::DPath::Path::BEGIN@1.2 at line 20
use List::Util 'min';
# spent 41µs making 1 call to Data::DPath::Context::BEGIN@20 # spent 8µs making 1 call to List::Util::import
21#use Sys::CPU;
22277µs28.33ms
# spent 5.71ms (2.38+3.33) within Data::DPath::Context::BEGIN@22 which was called: # once (2.38ms+3.33ms) by Data::DPath::Path::BEGIN@1.2 at line 22
use POSIX;
# spent 5.71ms making 1 call to Data::DPath::Context::BEGIN@22 # spent 2.63ms making 1 call to POSIX::import
232109µs110.1ms
# spent 10.1ms (1.65+8.45) within Data::DPath::Context::BEGIN@23 which was called: # once (1.65ms+8.45ms) by Data::DPath::Path::BEGIN@1.2 at line 23
use Safe;
# spent 10.1ms making 1 call to Data::DPath::Context::BEGIN@23
24
25# run filter expressions in own Safe.pm compartment
261200nsour $COMPARTMENT;
271100nsour $THREADCOUNT;
28
29
# spent 680µs (17+663) within Data::DPath::Context::BEGIN@29 which was called: # once (17µs+663µs) by Data::DPath::Path::BEGIN@1.2 at line 51
BEGIN {
30 #$THREADCOUNT = $Data::DPath::PARALLELIZE ? Sys::CPU::cpu_count : 1;
31 #print "THREADCOUNT: $THREADCOUNT\n";
32 package Data::DPath::Filters;
33
# spent 4µs within Data::DPath::Filters::BEGIN@33 which was called: # once (4µs+0s) by Data::DPath::Path::BEGIN@1.2 at line 35
BEGIN {
3414µs $Data::DPath::Filters::AUTHORITY = 'cpan:SCHWIGON';
35143µs14µs}
# spent 4µs making 1 call to Data::DPath::Filters::BEGIN@33
36{
372500ns $Data::DPath::Filters::VERSION = '0.49';
38}
3912µs1532µs $COMPARTMENT = Safe->new;
# spent 532µs making 1 call to Safe::new
4012µs113µs $COMPARTMENT->permit(qw":base_core");
# spent 13µs making 1 call to Safe::permit
41 # map DPath filter functions into new namespace
4216µs1118µs $COMPARTMENT->share(qw(affe
# spent 118µs making 1 call to Safe::share
43 idx
44 size
45 key
46 value
47 isa
48 reftype
49 is_reftype
50 ));
51142µs1680µs}
# spent 680µs making 1 call to Data::DPath::Context::BEGIN@29
52
53# print "use $]\n" if $] >= 5.010; # allow new-school Perl inside filter expressions
54# eval "use $]" if $] >= 5.010; # allow new-school Perl inside filter expressions
55
56use Class::XSAccessor::Array
57111µs1169µs
# spent 184µs (15+169) within Data::DPath::Context::BEGIN@57 which was called: # once (15µs+169µs) by Data::DPath::Path::BEGIN@1.2 at line 62
chained => 1,
# spent 169µs making 1 call to Class::XSAccessor::Array::import
58 constructor => 'new',
59 accessors => {
60 current_points => 0,
61 give_references => 1,
62164µs1184µs };
# spent 184µs making 1 call to Data::DPath::Context::BEGIN@57
63
64119µs1206µs
# spent 225µs (19+206) within Data::DPath::Context::BEGIN@64 which was called: # once (19µs+206µs) by Data::DPath::Path::BEGIN@1.2 at line 75
use constant { HASH => 'HASH',
# spent 206µs making 1 call to constant::import
65 ARRAY => 'ARRAY',
66 SCALAR => 'SCALAR',
67 ROOT => 'ROOT',
68 ANYWHERE => 'ANYWHERE',
69 KEY => 'KEY',
70 ANYSTEP => 'ANYSTEP',
71 NOSTEP => 'NOSTEP',
72 PARENT => 'PARENT',
73 ANCESTOR => 'ANCESTOR',
74 ANCESTOR_OR_SELF => 'ANCESTOR_OR_SELF',
751181µs1225µs };
# spent 225µs making 1 call to Data::DPath::Context::BEGIN@64
76
77sub _splice_threads {
78 my ($cargo) = @_;
79
80 my $nr_cargo = @$cargo;
81
82 return [[]] unless $nr_cargo;
83
84 my $threadcount = $THREADCOUNT || 1;
85 my $blocksize = ceil ($nr_cargo / $threadcount);
86
87 my @result = map {
88 my $first = $_ * $blocksize;
89 my $last = min(($_+1) * $blocksize - 1, $nr_cargo-1);
90 ($first <= $last) ? [ @$cargo[$first .. $last]] : ();
91 } 0 .. $threadcount-1;
92
93 return \@result;
94}
95
96# only finds "inner" values; if you need the outer start value
97# then just wrap it into one more level of array brackets.
98sub _any
99
# spent 591µs (543+48) within Data::DPath::Context::_any which was called 8 times, avg 74µs/call: # 7 times (457µs+-457µs) by Data::DPath::Context::_any at line 152, avg 0s/call # once (86µs+505µs) by Data::DPath::Context::_select_anywhere at line 270
{
10087µs my ($out, $in, $lookahead_key) = @_;
101
1022422µs252µs
# spent 34µs (16+18) within Data::DPath::Context::BEGIN@102 which was called: # once (16µs+18µs) by Data::DPath::Path::BEGIN@1.2 at line 102
no warnings 'uninitialized';
# spent 34µs making 1 call to Data::DPath::Context::BEGIN@102 # spent 18µs making 1 call to warnings::unimport
103
10483µs $in = defined $in ? $in : [];
10589µs return @$out unless @$in;
106
10771µs my @newin;
1087700ns my @newout;
10971µs my $tmp_ref;
1107700ns my $tmp_deref;
1117900ns my $tmp_reftype;
112
11379µs foreach my $point (@$in) {
114223µs my @values;
115223µs next unless defined $point;
1162220µs12µs my $ref = $point->ref;
# spent 2µs making 1 call to Data::DPath::Point::ref
117
118 # speed optimization: first try faster ref, then reftype
11922184µs3424µs if (ref($$ref) eq HASH or reftype($$ref) eq HASH) {
# spent 24µs making 34 calls to Scalar::Util::reftype, avg 712ns/call
120 @values =
121 map { { val_ref => \($$ref->{$_}), key => $_ } }
122 grep {
123 # speed optimization: only consider a key if lookahead looks promising
124 not defined $lookahead_key
125 or $_ eq $lookahead_key
126 or ($tmp_ref = ref($tmp_deref =$$ref->{$_})) eq HASH
127 or $tmp_ref eq ARRAY
128 or ($tmp_reftype = reftype($tmp_deref)) eq HASH
129 or $tmp_reftype eq ARRAY
130 # or HASH_or_ARRAY(\($$ref->{$_}))
131 }
132 keys %{$$ref};
133 }
134 elsif (ref($$ref) eq ARRAY or reftype($$ref) eq ARRAY) {
1351415µs @values = map { { val_ref => \$_ } } @{$$ref}
136 }
137 else {
138 next
139126µs }
140
1411020µs foreach (@values)
142 {
1432111µs my $key = $_->{key};
144216µs my $val_ref = $_->{val_ref};
14521144µs37µs my $newpoint = Point->new->ref($val_ref)->parent($point);
# spent 3µs making 1 call to Data::DPath::Point::new # spent 2µs making 1 call to Data::DPath::Point::parent # spent 1µs making 1 call to Data::DPath::Point::ref
1462159µs216µs $newpoint->attrs( Attrs->new(key => $key)) if $key;
# spent 14µs making 1 call to Data::DPath::Attrs::new # spent 2µs making 1 call to Data::DPath::Point::attrs
147219µs push @newout, $newpoint;
1482119µs push @newin, $newpoint;
149 }
150 }
15175µs push @$out, @newout;
152755µs70s return _any ($out, \@newin, $lookahead_key);
# spent 2.03ms making 7 calls to Data::DPath::Context::_any, avg 290µs/call, recursion: max depth 7, sum of overlapping time 2.03ms
153}
154
155
# spent 54µs (34+21) within Data::DPath::Context::_all which was called 2 times, avg 27µs/call: # 2 times (34µs+21µs) by Data::DPath::Context::match at line 475, avg 27µs/call
sub _all {
15621µs my ($self) = @_;
157
158235µs251µs
# spent 32µs (14+19) within Data::DPath::Context::BEGIN@158 which was called: # once (14µs+19µs) by Data::DPath::Path::BEGIN@1.2 at line 158
no strict 'refs';
# spent 32µs making 1 call to Data::DPath::Context::BEGIN@158 # spent 18µs making 1 call to strict::unimport
1592202µs235µs
# spent 24µs (12+12) within Data::DPath::Context::BEGIN@159 which was called: # once (12µs+12µs) by Data::DPath::Path::BEGIN@1.2 at line 159
no warnings 'uninitialized';
# spent 24µs making 1 call to Data::DPath::Context::BEGIN@159 # spent 12µs making 1 call to warnings::unimport
160
161 return
16226µs11µs map { $self->give_references ? $_ : $$_ }
# spent 1µs making 1 call to Data::DPath::Point::ref
163 uniq
164 map { defined $_ ? $_->ref : () }
165250µs420µs @{$self->current_points};
# spent 17µs making 2 calls to List::MoreUtils::uniq, avg 8µs/call # spent 2µs making 1 call to Data::DPath::Context::current_points # spent 900ns making 1 call to Data::DPath::Context::give_references
166}
167
168# filter current results by array index
169
# spent 9µs within Data::DPath::Context::_filter_points_index which was called 2 times, avg 5µs/call: # 2 times (9µs+0s) by Data::DPath::Context::_filter_points at line 232, avg 5µs/call
sub _filter_points_index {
17022µs my ($self, $index, $points) = @_;
171
172211µs return $points ? [$points->[$index]] : [];
173}
174
175# filter current results by condition
176sub _filter_points_eval
177{
178 my ($self, $filter, $points) = @_;
179
180 return [] unless @$points;
181 return $points unless defined $filter;
182
183 my $new_points;
184 my $res;
185 {
186 package Data::DPath::Filters;
187
188 local our $idx = 0;
189 $new_points = [
190 grep {
191 local our $p = $_;
192 local $_;
193 my $pref = $p->ref;
194 if ( defined $pref ) {
195 $_ = $$pref;
196 if ($Data::DPath::USE_SAFE) {
197 # 'uninitialized' values are the norm
198 # but "no warnings 'uninitialized'" does
199 # not work in this restrictive Safe.pm config, so
200 # we deactivate warnings completely by localizing $^W
201 $res = $COMPARTMENT->reval('local $^W;'.$filter);
202 } else {
203 # 'uninitialized' values are the norm
204287µs259µs
# spent 36µs (13+23) within Data::DPath::Filters::BEGIN@204 which was called: # once (13µs+23µs) by Data::DPath::Path::BEGIN@1.2 at line 204
no warnings 'uninitialized';
# spent 36µs making 1 call to Data::DPath::Filters::BEGIN@204 # spent 23µs making 1 call to warnings::unimport
205 $res = eval($filter);
206 }
207 print STDERR ($@, "\n") if $@;
208 } else {
209 $res = 0;
210 }
211 $idx++;
212 $res;
213 } @$points
214 ];
215 }
216 return $new_points;
217}
218
219
# spent 146µs (117+29) within Data::DPath::Context::_filter_points which was called 29 times, avg 5µs/call: # 18 times (42µs+0s) by Data::DPath::Context::_select_key at line 296, avg 2µs/call # 6 times (20µs+2µs) by Data::DPath::Context::_select_root at line 251, avg 4µs/call # 2 times (47µs+27µs) by Data::DPath::Context::_select_anystep at line 330, avg 37µs/call # 2 times (5µs+0s) by Data::DPath::Context::_select_ancestor at line 368, avg 2µs/call # once (3µs+0s) by Data::DPath::Context::_select_anywhere at line 271
sub _filter_points {
2202914µs my ($self, $step, $points) = @_;
221
222221µs226µs
# spent 17µs (8+9) within Data::DPath::Context::BEGIN@222 which was called: # once (8µs+9µs) by Data::DPath::Path::BEGIN@1.2 at line 222
no strict 'refs';
# spent 17µs making 1 call to Data::DPath::Context::BEGIN@222 # spent 9µs making 1 call to strict::unimport
2232210µs222µs
# spent 15µs (8+7) within Data::DPath::Context::BEGIN@223 which was called: # once (8µs+7µs) by Data::DPath::Path::BEGIN@1.2 at line 223
no warnings 'uninitialized';
# spent 15µs making 1 call to Data::DPath::Context::BEGIN@223 # spent 7µs making 1 call to warnings::unimport
224
2252926µs return [] unless @$points;
226
2272317µs12µs my $filter = $step->filter;
# spent 2µs making 1 call to Data::DPath::Step::filter
2282371µs return $points unless defined $filter;
229
230236µs613µs $filter =~ s/^\[\s*(.*?)\s*\]$/$1/; # strip brackets and whitespace
# spent 8µs making 2 calls to Data::DPath::Context::CORE:subst, avg 4µs/call # spent 4µs making 4 calls to Data::DPath::Context::CORE:substcont, avg 1µs/call
231
232226µs415µs if ($filter =~ /^-?\d+$/)
# spent 9µs making 2 calls to Data::DPath::Context::_filter_points_index, avg 5µs/call # spent 5µs making 2 calls to Data::DPath::Context::CORE:match, avg 3µs/call
233 {
234 return $self->_filter_points_index($filter, $points); # simple array index
235 }
236 elsif ($filter =~ /\S/)
237 {
238 return $self->_filter_points_eval($filter, $points); # full condition
239 }
240 else
241 {
242 return $points;
243 }
244}
245
246# the root node
247# (only makes sense at first step, but currently not asserted)
248
# spent 65µs (43+23) within Data::DPath::Context::_select_root which was called 6 times, avg 11µs/call: # 6 times (43µs+23µs) by Data::DPath::Context::_search at line 434, avg 11µs/call
sub _select_root {
24964µs my ($self, $step, $current_points, $new_points) = @_;
250
25169µs623µs my $step_points = $self->_filter_points($step, $current_points);
# spent 23µs making 6 calls to Data::DPath::Context::_filter_points, avg 4µs/call
252623µs push @$new_points, @$step_points;
253}
254
255
256# //
257# anywhere in the tree
258
# spent 631µs (34+596) within Data::DPath::Context::_select_anywhere which was called: # once (34µs+596µs) by Data::DPath::Context::_search at line 434
sub _select_anywhere {
25911µs my ($self, $step, $current_points, $lookahead, $new_points) = @_;
260
261 # speed optimization: only useful points added
2621300ns my $lookahead_key;
263112µs22µs if (defined $lookahead and $lookahead->kind eq KEY) {
# spent 2µs making 1 call to Data::DPath::Step::kind # spent 800ns making 1 call to Data::DPath::Step::part
264 $lookahead_key = $lookahead->part;
265 }
266
267 # '//'
268 # all hash/array nodes of a data structure
26918µs foreach my $point (@$current_points) {
27019µs1591µs my $step_points = [_any([], [ $point ], $lookahead_key), $point];
# spent 591µs making 1 call to Data::DPath::Context::_any
27116µs13µs push @$new_points, @{$self->_filter_points($step, $step_points)};
# spent 3µs making 1 call to Data::DPath::Context::_filter_points
272 }
273}
274
275# /key
276# the value of a key
277
# spent 425µs (362+63) within Data::DPath::Context::_select_key which was called 11 times, avg 39µs/call: # 11 times (362µs+63µs) by Data::DPath::Context::_search at line 434, avg 39µs/call
sub _select_key {
278116µs my ($self, $step, $current_points, $new_points) = @_;
279
2801140µs foreach my $point (@$current_points) {
2812114µs224µs
# spent 16µs (9+7) within Data::DPath::Context::BEGIN@281 which was called: # once (9µs+7µs) by Data::DPath::Path::BEGIN@1.2 at line 281
no warnings 'uninitialized';
# spent 16µs making 1 call to Data::DPath::Context::BEGIN@281 # spent 8µs making 1 call to warnings::unimport
282325µs next unless defined $point;
2833223µs1900ns my $pref = $point->ref;
# spent 900ns making 1 call to Data::DPath::Point::ref
284 next unless (
285 # speed optimization:
286 # first try faster ref, then reftype
2873260µs1410µs ref($$pref) eq HASH or
# spent 10µs making 14 calls to Scalar::Util::reftype, avg 700ns/call
288 reftype($$pref) eq HASH
289 );
290 # take point as hash, skip undefs
2911873µs23µs my $attrs = Attrs->new(key => $step->part);
# spent 2µs making 1 call to Data::DPath::Attrs::new # spent 700ns making 1 call to Data::DPath::Step::part
292187µs my $step_points = [];
2931897µs68µs if (exists $$pref->{$step->part}) {
# spent 3µs making 2 calls to Data::DPath::Step::part, avg 1µs/call # spent 2µs making 1 call to Data::DPath::Point::new # spent 1µs making 1 call to Data::DPath::Point::ref # spent 1µs making 1 call to Data::DPath::Point::parent # spent 900ns making 1 call to Data::DPath::Point::attrs
294 $step_points = [ Point->new->ref(\($$pref->{$step->part}))->parent($point)->attrs($attrs) ];
295 }
2961856µs1842µs push @$new_points, @{$self->_filter_points($step, $step_points)};
# spent 42µs making 18 calls to Data::DPath::Context::_filter_points, avg 2µs/call
297 }
298}
299
300# '*'
301# all leaves of a data tree
302
# spent 184µs (101+83) within Data::DPath::Context::_select_anystep which was called 2 times, avg 92µs/call: # 2 times (101µs+83µs) by Data::DPath::Context::_search at line 434, avg 92µs/call
sub _select_anystep {
30322µs my ($self, $step, $current_points, $new_points) = @_;
304
3052461µs222µs
# spent 15µs (8+7) within Data::DPath::Context::BEGIN@305 which was called: # once (8µs+7µs) by Data::DPath::Path::BEGIN@1.2 at line 305
no warnings 'uninitialized';
# spent 15µs making 1 call to Data::DPath::Context::BEGIN@305 # spent 7µs making 1 call to warnings::unimport
306210µs foreach my $point (@$current_points) {
307 # take point as array
30827µs11µs my $pref = $point->ref;
# spent 1µs making 1 call to Data::DPath::Point::ref
3092900ns my $ref = $$pref;
31021µs my $step_points = [];
311 # speed optimization: first try faster ref, then reftype
312214µs23µs if (ref($ref) eq HASH or reftype($ref) eq HASH) {
# spent 3µs making 2 calls to Scalar::Util::reftype, avg 1µs/call
313 $step_points = [ map {
314 my $v_ref = \($ref->{$_});
315 my $attrs = Attrs->new(key => $_);
316 Point->new->ref($v_ref)->parent($point)->attrs($attrs)
317 } keys %$ref ];
318 } elsif (ref($ref) eq ARRAY or reftype($ref) eq ARRAY) {
3191253µs35µs $step_points = [ map {
# spent 3µs making 1 call to Data::DPath::Point::new # spent 1µs making 1 call to Data::DPath::Point::parent # spent 1µs making 1 call to Data::DPath::Point::ref
320211µs Point->new->ref(\$_)->parent($point)
321 } @$ref ];
322 } else {
323 if (ref($pref) eq SCALAR or reftype($pref) eq SCALAR) {
324 # TODO: without map, it's just one value
325 $step_points = [ #map {
326 Point->new->ref($pref)->parent($point) # XXX? why $_? What happens to $pref?
327 ]; # } $ref ];
328 }
329 }
330211µs274µs push @$new_points, @{ $self->_filter_points($step, $step_points) };
# spent 74µs making 2 calls to Data::DPath::Context::_filter_points, avg 37µs/call
331 }
332}
333
334# '.'
335# no step (neither up nor down), just allow filtering
336sub _select_nostep {
337 my ($self, $step, $current_points, $new_points) = @_;
338
339 foreach my $point (@{$current_points}) {
340 my $step_points = [$point];
341 push @$new_points, @{ $self->_filter_points($step, $step_points) };
342 }
343}
344
345# '..'
346# the parent
347sub _select_parent {
348 my ($self, $step, $current_points, $new_points) = @_;
349
350 foreach my $point (@{$current_points}) {
351 next unless defined $point;
352 my $step_points = [$point->parent];
353 push @$new_points, @{ $self->_filter_points($step, $step_points) };
354 }
355}
356
357# '::ancestor'
358# all ancestors (parent, grandparent, etc.) of the current node
359
# spent 46µs (40+7) within Data::DPath::Context::_select_ancestor which was called 2 times, avg 23µs/call: # 2 times (40µs+7µs) by Data::DPath::Context::_search at line 434, avg 23µs/call
sub _select_ancestor {
36022µs my ($self, $step, $current_points, $new_points) = @_;
361
36229µs foreach my $point (@{$current_points}) {
36321µs my $step_points = [];
3642400ns my $parent = $point;
36529µs12µs while ($parent = $parent->parent) {
# spent 2µs making 1 call to Data::DPath::Point::parent
366109µs push @$step_points, $parent; # order matters
367 }
36828µs25µs push @$new_points, @{ $self->_filter_points($step, $step_points) };
# spent 5µs making 2 calls to Data::DPath::Context::_filter_points, avg 2µs/call
369 }
370}
371
372# '::ancestor-or-self'
373# all ancestors (parent, grandparent, etc.) of the current node and the current node itself
374sub _select_ancestor_or_self {
375 my ($self, $step, $current_points, $new_points) = @_;
376
377 foreach my $point (@{$current_points}) {
378 my $step_points = [$point];
379 my $parent = $point;
380 while ($parent = $parent->parent) {
381 push @$step_points, $parent; # order matters
382 }
383 push @$new_points, @{ $self->_filter_points($step, $step_points) };
384 }
385}
386
387sub ref {
388 my ($self) = @_;
389 $self->first_point->{ref};
390}
391
392sub deref {
393 my ($self) = @_;
394 ${$self->ref};
395}
396
397
# spent 29µs (28+800ns) within Data::DPath::Context::first_point which was called 10 times, avg 3µs/call: # 10 times (28µs+800ns) by Benchmark::Perl::Formance::find_interesting_result_paths at line 706 of lib/Benchmark/Perl/Formance.pm, avg 3µs/call
sub first_point {
398105µs my ($self) = @_;
3991039µs1800ns $self->current_points->[0];
# spent 800ns making 1 call to Data::DPath::Context::current_points
400}
401
402sub all_points {
403 my ($self) = @_;
404 iarray $self->current_points;
405}
406
407
# spent 1.61ms (49µs+1.56) within Data::DPath::Context::_iter which was called 4 times, avg 403µs/call: # 3 times (27µs+332µs) by Data::DPath::Context::isearch at line 417, avg 120µs/call # once (22µs+1.23ms) 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
sub _iter {
40842µs my ($self) = @_;
409
410419µs5218µs my $iter = iarray $self->current_points;
# spent 216µs making 4 calls to Iterator::Util::iarray, avg 54µs/call # spent 2µs making 1 call to Data::DPath::Context::current_points
41117136µs61.35ms
# spent 79µs (75+4) within Data::DPath::Context::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath/Context.pm:411] which was called 13 times, avg 6µs/call: # 13 times (75µs+4µs) by Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:52] at line 51 of Iterator/Util.pm, avg 6µs/call
return imap { __PACKAGE__->new->current_points([ $_ ]) } $iter;
# spent 1.34ms making 4 calls to Iterator::Util::imap, avg 336µs/call # spent 2µs making 1 call to Data::DPath::Context::new # spent 1µs making 1 call to Data::DPath::Context::current_points
412}
413
414sub isearch
415
# spent 1.92ms (45µs+1.87) within Data::DPath::Context::isearch which was called 3 times, avg 639µs/call: # 2 times (26µs+571µs) by Benchmark::Perl::Formance::find_interesting_result_paths at line 703 of lib/Benchmark/Perl/Formance.pm, avg 298µs/call # once (19µs+1.30ms) by Benchmark::Perl::Formance::find_interesting_result_paths at line 698 of lib/Benchmark/Perl/Formance.pm
{
41632µs my ($self, $path_str) = @_;
417331µs91.87ms $self->_search(Data::DPath::Path->new(path => $path_str))->_iter;
# spent 1.03ms making 3 calls to Data::DPath::Context::_search, avg 344µs/call # spent 481µs making 3 calls to Data::DPath::Path::new, avg 160µs/call # spent 359µs making 3 calls to Data::DPath::Context::_iter, avg 120µs/call
418}
419
420sub _search
421
# spent 1.59ms (231µs+1.36) within Data::DPath::Context::_search which was called 6 times, avg 266µs/call: # 3 times (96µs+936µs) by Data::DPath::Context::isearch at line 417, avg 344µs/call # 2 times (100µs+399µs) by Data::DPath::Context::match at line 475, avg 249µs/call # once (35µs+29µ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
{
42263µs my ($self, $dpath) = @_;
423
424220µs226µs
# spent 17µs (7+10) within Data::DPath::Context::BEGIN@424 which was called: # once (7µs+10µs) by Data::DPath::Path::BEGIN@1.2 at line 424
no strict 'refs';
# spent 17µs making 1 call to Data::DPath::Context::BEGIN@424 # spent 10µs making 1 call to strict::unimport
4252188µs223µs
# spent 16µs (10+7) within Data::DPath::Context::BEGIN@425 which was called: # once (10µs+7µs) by Data::DPath::Path::BEGIN@1.2 at line 425
no warnings 'uninitialized';
# spent 16µs making 1 call to Data::DPath::Context::BEGIN@425 # spent 7µs making 1 call to warnings::unimport
426
427610µs12µs my $current_points = $self->current_points;
# spent 2µs making 1 call to Data::DPath::Context::current_points
42868µs1900ns my $steps = $dpath->_steps;
# spent 900ns making 1 call to Data::DPath::Path::_steps
429627µs for (my $i = 0; $i < @$steps; $i++) {
430228µs my $step = $steps->[$i];
4312210µs my $lookahead = $steps->[$i+1];
4322210µs my $new_points = [];
433
4342299µs291.36ms if ($step->kind eq ROOT)
# spent 631µs making 1 call to Data::DPath::Context::_select_anywhere # spent 425µs making 11 calls to Data::DPath::Context::_select_key, avg 39µs/call # spent 184µs making 2 calls to Data::DPath::Context::_select_anystep, avg 92µs/call # spent 65µs making 6 calls to Data::DPath::Context::_select_root, avg 11µs/call # spent 46µs making 2 calls to Data::DPath::Context::_select_ancestor, avg 23µs/call # spent 7µs making 7 calls to Data::DPath::Step::kind, avg 1µs/call
435 {
436 $self->_select_root($step, $current_points, $new_points);
437 }
438 elsif ($step->kind eq ANYWHERE)
439 {
440 $self->_select_anywhere($step, $current_points, $lookahead, $new_points);
441 }
442 elsif ($step->kind eq KEY)
443 {
444 $self->_select_key($step, $current_points, $new_points);
445 }
446 elsif ($step->kind eq ANYSTEP)
447 {
448 $self->_select_anystep($step, $current_points, $new_points);
449 }
450 elsif ($step->kind eq NOSTEP)
451 {
452 $self->_select_nostep($step, $current_points, $new_points);
453 }
454 elsif ($step->kind eq PARENT)
455 {
456 $self->_select_parent($step, $current_points, $new_points);
457 }
458 elsif ($step->kind eq ANCESTOR)
459 {
460 $self->_select_ancestor($step, $current_points, $new_points);
461 }
462 elsif ($step->kind eq ANCESTOR_OR_SELF)
463 {
464 $self->_select_ancestor_or_self($step, $current_points, $new_points);
465 }
4662213µs $current_points = $new_points;
467 }
468612µs12µs $self->current_points( $current_points );
# spent 2µs making 1 call to Data::DPath::Context::current_points
469626µs return $self;
470}
471
472
# spent 572µs (19+553) within Data::DPath::Context::match which was called 2 times, avg 286µs/call: # 2 times (19µs+553µs) by Data::DPath::Path::match at line 143 of Data/DPath/Path.pm, avg 286µs/call
sub match {
47321µs my ($self, $dpath) = @_;
474
475216µs4553µs $self->_search($dpath)->_all;
# spent 499µs making 2 calls to Data::DPath::Context::_search, avg 249µs/call # spent 54µs making 2 calls to Data::DPath::Context::_all, avg 27µs/call
476}
477
47813µs1;
479
480__END__
 
# spent 5µs within Data::DPath::Context::CORE:match which was called 2 times, avg 3µs/call: # 2 times (5µs+0s) by Data::DPath::Context::_filter_points at line 232, avg 3µs/call
sub Data::DPath::Context::CORE:match; # opcode
# spent 8µs within Data::DPath::Context::CORE:subst which was called 2 times, avg 4µs/call: # 2 times (8µs+0s) by Data::DPath::Context::_filter_points at line 230, avg 4µs/call
sub Data::DPath::Context::CORE:subst; # opcode
# spent 4µs within Data::DPath::Context::CORE:substcont which was called 4 times, avg 1µs/call: # 4 times (4µs+0s) by Data::DPath::Context::_filter_points at line 230, avg 1µs/call
sub Data::DPath::Context::CORE:substcont; # opcode
# spent 14µs within Data::DPath::Context::current_points which was called 8 times, avg 2µs/call: # once (4µs+0s) 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 # once (2µs+0s) by Data::DPath::Context::_search at line 468 # once (2µs+0s) by Data::DPath::Context::_all at line 165 # once (2µs+0s) by Data::DPath::Context::_search at line 427 # once (2µs+0s) by Data::DPath::Context::_iter at line 410 # once (1µs+0s) by Data::DPath::Path::match at line 139 of Data/DPath/Path.pm # once (1µs+0s) by Data::DPath::Context::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath/Context.pm:411] at line 411 # once (800ns+0s) by Data::DPath::Context::first_point at line 399
sub Data::DPath::Context::current_points; # xsub
# spent 2µs within Data::DPath::Context::give_references which was called 2 times, avg 800ns/call: # once (900ns+0s) by Data::DPath::Context::_all at line 165 # once (700ns+0s) by Data::DPath::Path::match at line 139 of Data/DPath/Path.pm
sub Data::DPath::Context::give_references; # xsub
# spent 28µs within Data::DPath::Context::new which was called 3 times, avg 9µs/call: # once (24µs+0s) 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 # once (2µs+0s) by Data::DPath::Path::match at line 139 of Data/DPath/Path.pm # once (2µs+0s) by Data::DPath::Context::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath/Context.pm:411] at line 411
sub Data::DPath::Context::new; # xsub