Filename | /Users/ap13/perl5/lib/perl5/Graph/AdjacencyMap.pm |
Statements | Executed 1018859 statements in 876ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
24876 | 1 | 1 | 381ms | 1.42s | _successors | Graph::AdjacencyMap::
19958 | 1 | 1 | 341ms | 505ms | _set_path_attr | Graph::AdjacencyMap::
5007 | 1 | 1 | 60.5ms | 146ms | _get_path_attr | Graph::AdjacencyMap::
59852 | 1 | 1 | 53.1ms | 53.1ms | _is_MULTI | Graph::AdjacencyMap::
14965 | 1 | 1 | 48.0ms | 48.0ms | _new_node | Graph::AdjacencyMap::
5007 | 1 | 1 | 47.0ms | 48.8ms | __get_path_node | Graph::AdjacencyMap::
24952 | 2 | 1 | 27.1ms | 27.1ms | _is_UNORD | Graph::AdjacencyMap::
49930 | 4 | 1 | 27.1ms | 27.1ms | CORE:sort (opcode) | Graph::AdjacencyMap::
4993 | 1 | 1 | 9.67ms | 9.67ms | _inc_node | Graph::AdjacencyMap::
67 | 1 | 1 | 303µs | 303µs | _new | Graph::AdjacencyMap::
67 | 1 | 1 | 168µs | 168µs | _ids | Graph::AdjacencyMap::
31 | 1 | 1 | 66µs | 66µs | _is_COUNT | Graph::AdjacencyMap::
1 | 1 | 1 | 12µs | 24µs | BEGIN@3 | Graph::AdjacencyMap::
1 | 1 | 1 | 8µs | 59µs | BEGIN@6 | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _GEN_ID | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | __arg | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _del_id | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _del_path_attr | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _del_path_attrs | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _dump | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _get_path_attr_names | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _get_path_attr_values | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _get_path_attrs | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _has_path_attr | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _has_path_attrs | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _is_HYPER | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _is_REF | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _is_STR | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _is_UNIQ | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _predecessors | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | _set_path_attrs | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | get_multi_ids | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | has_paths | Graph::AdjacencyMap::
0 | 0 | 0 | 0s | 0s | set_path_by_multi_id | Graph::AdjacencyMap::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Graph::AdjacencyMap; | ||||
2 | |||||
3 | 2 | 29µs | 2 | 37µs | # spent 24µs (12+12) within Graph::AdjacencyMap::BEGIN@3 which was called:
# once (12µs+12µs) by Graph::BEGIN@13 at line 3 # spent 24µs making 1 call to Graph::AdjacencyMap::BEGIN@3
# spent 12µs making 1 call to strict::import |
4 | |||||
5 | 1 | 900ns | require Exporter; | ||
6 | 2 | 2.74ms | 2 | 109µs | # spent 59µs (8+51) within Graph::AdjacencyMap::BEGIN@6 which was called:
# once (8µs+51µs) by Graph::BEGIN@13 at line 6 # spent 59µs making 1 call to Graph::AdjacencyMap::BEGIN@6
# spent 51µs making 1 call to vars::import |
7 | 1 | 9µs | @ISA = qw(Exporter); | ||
8 | 1 | 4µs | @EXPORT_OK = qw(_COUNT _MULTI _COUNTMULTI _GEN_ID | ||
9 | _HYPER _UNORD _UNIQ _REF _UNORDUNIQ _UNIONFIND _LIGHT | ||||
10 | _STR _REFSTR | ||||
11 | _n _f _a _i _s _p _g _u _ni _nc _na _nm); | ||||
12 | 1 | 6µs | %EXPORT_TAGS = | ||
13 | (flags => [qw(_COUNT _MULTI _COUNTMULTI _GEN_ID | ||||
14 | _HYPER _UNORD _UNIQ _REF _UNORDUNIQ _UNIONFIND _LIGHT | ||||
15 | _STR _REFSTR)], | ||||
16 | fields => [qw(_n _f _a _i _s _p _g _u _ni _nc _na _nm)]); | ||||
17 | |||||
18 | sub _COUNT () { 0x00000001 } | ||||
19 | sub _MULTI () { 0x00000002 } | ||||
20 | sub _COUNTMULTI () { _COUNT|_MULTI } | ||||
21 | sub _HYPER () { 0x00000004 } | ||||
22 | sub _UNORD () { 0x00000008 } | ||||
23 | sub _UNIQ () { 0x00000010 } | ||||
24 | sub _REF () { 0x00000020 } | ||||
25 | sub _UNORDUNIQ () { _UNORD|_UNIQ } | ||||
26 | sub _UNIONFIND () { 0x00000040 } | ||||
27 | sub _LIGHT () { 0x00000080 } | ||||
28 | sub _STR () { 0x00000100 } | ||||
29 | sub _REFSTR () { _REF|_STR } | ||||
30 | |||||
31 | 1 | 400ns | my $_GEN_ID = 0; | ||
32 | |||||
33 | sub _GEN_ID () { \$_GEN_ID } | ||||
34 | |||||
35 | sub _ni () { 0 } # Node index. | ||||
36 | sub _nc () { 1 } # Node count. | ||||
37 | sub _na () { 2 } # Node attributes. | ||||
38 | sub _nm () { 3 } # Node map. | ||||
39 | |||||
40 | sub _n () { 0 } # Next id. | ||||
41 | sub _f () { 1 } # Flags. | ||||
42 | sub _a () { 2 } # Arity. | ||||
43 | sub _i () { 3 } # Index to path. | ||||
44 | sub _s () { 4 } # Successors / Path to Index. | ||||
45 | sub _p () { 5 } # Predecessors. | ||||
46 | sub _g () { 6 } # Graph (AdjacencyMap::Light) | ||||
47 | |||||
48 | sub _V () { 2 } # Graph::_V() | ||||
49 | |||||
50 | # spent 303µs within Graph::AdjacencyMap::_new which was called 67 times, avg 5µs/call:
# 67 times (303µs+0s) by Graph::AdjacencyMap::Light::__attr at line 226 of Graph/AdjacencyMap/Light.pm, avg 5µs/call | ||||
51 | 67 | 41µs | my $class = shift; | ||
52 | 67 | 132µs | my $map = bless [ 0, @_ ], $class; | ||
53 | 67 | 177µs | return $map; | ||
54 | } | ||||
55 | |||||
56 | # spent 168µs within Graph::AdjacencyMap::_ids which was called 67 times, avg 3µs/call:
# 67 times (168µs+0s) by Graph::_edges at line 794 of Graph.pm, avg 3µs/call | ||||
57 | 67 | 26µs | my $m = shift; | ||
58 | 67 | 199µs | return $m->[ _i ]; | ||
59 | } | ||||
60 | |||||
61 | sub has_paths { | ||||
62 | my $m = shift; | ||||
63 | return defined $m->[ _i ] && keys %{ $m->[ _i ] }; | ||||
64 | } | ||||
65 | |||||
66 | sub _dump { | ||||
67 | my $d = Data::Dumper->new([$_[0]],[ref $_[0]]); | ||||
68 | defined wantarray ? $d->Dump : print $d->Dump; | ||||
69 | } | ||||
70 | |||||
71 | sub _del_id { | ||||
72 | my ($m, $i) = @_; | ||||
73 | my @p = $m->_get_id_path( $i ); | ||||
74 | $m->del_path( @p ) if @p; | ||||
75 | } | ||||
76 | |||||
77 | # spent 48.0ms within Graph::AdjacencyMap::_new_node which was called 14965 times, avg 3µs/call:
# 14965 times (48.0ms+0s) by Graph::AdjacencyMap::Heavy::__set_path_node at line 52 of Graph/AdjacencyMap/Heavy.pm, avg 3µs/call | ||||
78 | 14965 | 5.64ms | my ($m, $n, $id) = @_; | ||
79 | 14965 | 2.23ms | my $f = $m->[ _f ]; | ||
80 | 14965 | 3.45ms | my $i = $m->[ _n ]++; | ||
81 | 14965 | 8.11ms | if (($f & _MULTI)) { | ||
82 | $id = 0 if $id eq _GEN_ID; | ||||
83 | $$n = [ $i, 0, undef, { $id => { } } ]; | ||||
84 | } elsif (($f & _COUNT)) { | ||||
85 | $$n = [ $i, 1 ]; | ||||
86 | } else { | ||||
87 | 14965 | 3.89ms | $$n = $i; | ||
88 | } | ||||
89 | 14965 | 30.0ms | return $i; | ||
90 | } | ||||
91 | |||||
92 | # spent 9.67ms within Graph::AdjacencyMap::_inc_node which was called 4993 times, avg 2µs/call:
# 4993 times (9.67ms+0s) by Graph::AdjacencyMap::Heavy::__set_path_node at line 56 of Graph/AdjacencyMap/Heavy.pm, avg 2µs/call | ||||
93 | 4993 | 1.70ms | my ($m, $n, $id) = @_; | ||
94 | 4993 | 754µs | my $f = $m->[ _f ]; | ||
95 | 4993 | 1.17ms | if (($f & _MULTI)) { | ||
96 | if ($id eq _GEN_ID) { | ||||
97 | $$n->[ _nc ]++ | ||||
98 | while exists $$n->[ _nm ]->{ $$n->[ _nc ] }; | ||||
99 | $id = $$n->[ _nc ]; | ||||
100 | } | ||||
101 | $$n->[ _nm ]->{ $id } = { }; | ||||
102 | } elsif (($f & _COUNT)) { | ||||
103 | $$n->[ _nc ]++; | ||||
104 | } | ||||
105 | 4993 | 8.89ms | return $id; | ||
106 | } | ||||
107 | |||||
108 | # spent 48.8ms (47.0+1.79) within Graph::AdjacencyMap::__get_path_node which was called 5007 times, avg 10µs/call:
# 5007 times (47.0ms+1.79ms) by Graph::AdjacencyMap::_get_path_attr at line 262, avg 10µs/call | ||||
109 | 5007 | 1.17ms | my $m = shift; | ||
110 | 5007 | 820µs | my ($p, $k); | ||
111 | 5007 | 1.12ms | my $f = $m->[ _f ]; | ||
112 | 5007 | 9.95ms | 5007 | 1.79ms | @_ = sort @_ if ($f & _UNORD); # spent 1.79ms making 5007 calls to Graph::AdjacencyMap::CORE:sort, avg 357ns/call |
113 | 5007 | 2.91ms | if ($m->[ _a ] == 2 && @_ == 2 && !($f & (_HYPER|_REF|_UNIQ))) { # Fast path. | ||
114 | 5007 | 1.78ms | return unless exists $m->[ _s ]->{ $_[0] }; | ||
115 | 5007 | 5.24ms | $p = [ $m->[ _s ], $m->[ _s ]->{ $_[0] } ]; | ||
116 | 5007 | 5.14ms | $k = [ $_[0], $_[1] ]; | ||
117 | } else { | ||||
118 | ($p, $k) = $m->__has_path( @_ ); | ||||
119 | } | ||||
120 | 5007 | 1.10ms | return unless defined $p && defined $k; | ||
121 | 5007 | 1.87ms | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||
122 | 5007 | 16.8ms | return ( exists $p->[-1]->{ $l }, $p->[-1]->{ $l }, $p, $k, $l ); | ||
123 | } | ||||
124 | |||||
125 | sub set_path_by_multi_id { | ||||
126 | my $m = shift; | ||||
127 | my ($p, $k) = $m->__set_path( @_ ); | ||||
128 | return unless defined $p && defined $k; | ||||
129 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
130 | return $m->__set_path_node( $p, $l, @_ ); | ||||
131 | } | ||||
132 | |||||
133 | sub get_multi_ids { | ||||
134 | my $m = shift; | ||||
135 | my $f = $m->[ _f ]; | ||||
136 | return () unless ($f & _MULTI); | ||||
137 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
138 | return $e ? keys %{ $n->[ _nm ] } : (); | ||||
139 | } | ||||
140 | |||||
141 | sub _has_path_attrs { | ||||
142 | my $m = shift; | ||||
143 | my $f = $m->[ _f ]; | ||||
144 | my $id = pop if ($f & _MULTI); | ||||
145 | @_ = sort @_ if ($f & _UNORD); | ||||
146 | $m->__attr( \@_ ); | ||||
147 | if (($f & _MULTI)) { | ||||
148 | my ($p, $k) = $m->__has_path( @_ ); | ||||
149 | return unless defined $p && defined $k; | ||||
150 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
151 | return keys %{ $p->[-1]->{ $l }->[ _nm ]->{ $id } } ? 1 : 0; | ||||
152 | } else { | ||||
153 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
154 | return undef unless $e; | ||||
155 | return ref $n && $#$n == _na && keys %{ $n->[ _na ] } ? 1 : 0; | ||||
156 | } | ||||
157 | } | ||||
158 | |||||
159 | sub _set_path_attrs { | ||||
160 | my $m = shift; | ||||
161 | my $f = $m->[ _f ]; | ||||
162 | my $attr = pop; | ||||
163 | my $id = pop if ($f & _MULTI); | ||||
164 | @_ = sort @_ if ($f & _UNORD); | ||||
165 | $m->__attr( @_ ); | ||||
166 | push @_, $id if ($f & _MULTI); | ||||
167 | my ($p, $k) = $m->__set_path( @_ ); | ||||
168 | return unless defined $p && defined $k; | ||||
169 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
170 | $m->__set_path_node( $p, $l, @_ ) unless exists $p->[-1]->{ $l }; | ||||
171 | if (($f & _MULTI)) { | ||||
172 | $p->[-1]->{ $l }->[ _nm ]->{ $id } = $attr; | ||||
173 | } else { | ||||
174 | # Extend the node if it is a simple id node. | ||||
175 | $p->[-1]->{ $l } = [ $p->[-1]->{ $l }, 1 ] unless ref $p->[-1]->{ $l }; | ||||
176 | $p->[-1]->{ $l }->[ _na ] = $attr; | ||||
177 | } | ||||
178 | } | ||||
179 | |||||
180 | sub _has_path_attr { | ||||
181 | my $m = shift; | ||||
182 | my $f = $m->[ _f ]; | ||||
183 | my $attr = pop; | ||||
184 | my $id = pop if ($f & _MULTI); | ||||
185 | @_ = sort @_ if ($f & _UNORD); | ||||
186 | $m->__attr( \@_ ); | ||||
187 | if (($f & _MULTI)) { | ||||
188 | my ($p, $k) = $m->__has_path( @_ ); | ||||
189 | return unless defined $p && defined $k; | ||||
190 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
191 | exists $p->[-1]->{ $l }->[ _nm ]->{ $id }->{ $attr }; | ||||
192 | } else { | ||||
193 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
194 | return undef unless $e; | ||||
195 | return ref $n && $#$n == _na ? exists $n->[ _na ]->{ $attr } : undef; | ||||
196 | } | ||||
197 | } | ||||
198 | |||||
199 | # spent 505ms (341+165) within Graph::AdjacencyMap::_set_path_attr which was called 19958 times, avg 25µs/call:
# 19958 times (341ms+165ms) by Graph::set_edge_attribute at line 1469 of Graph.pm, avg 25µs/call | ||||
200 | 19958 | 4.49ms | my $m = shift; | ||
201 | 19958 | 4.38ms | my $f = $m->[ _f ]; | ||
202 | 19958 | 2.67ms | my $val = pop; | ||
203 | 19958 | 2.44ms | my $attr = pop; | ||
204 | 19958 | 2.56ms | my $id = pop if ($f & _MULTI); | ||
205 | 19958 | 47.4ms | 19958 | 14.6ms | @_ = sort @_ if ($f & _UNORD); # spent 14.6ms making 19958 calls to Graph::AdjacencyMap::CORE:sort, avg 730ns/call |
206 | 19958 | 2.66ms | my ($p, $k); | ||
207 | 19958 | 25.1ms | 19958 | 142ms | $m->__attr( \@_ ); # _LIGHT maps need this to get upgraded when needed. # spent 128ms making 19891 calls to Graph::AdjacencyMap::Heavy::__attr, avg 6µs/call
# spent 13.9ms making 67 calls to Graph::AdjacencyMap::Light::__attr, avg 208µs/call |
208 | 19958 | 2.65ms | push @_, $id if ($f & _MULTI); | ||
209 | 19958 | 36.7ms | 19958 | 7.19ms | @_ = sort @_ if ($f & _UNORD); # spent 7.19ms making 19958 calls to Graph::AdjacencyMap::CORE:sort, avg 360ns/call |
210 | 19958 | 12.9ms | if ($m->[ _a ] == 2 && @_ == 2 && !($f & (_REF|_UNIQ|_HYPER|_UNIQ))) { | ||
211 | 19958 | 7.62ms | $m->[ _s ]->{ $_[0] } ||= { }; | ||
212 | 19958 | 17.1ms | $p = [ $m->[ _s ], $m->[ _s ]->{ $_[0] } ]; | ||
213 | 19958 | 16.2ms | $k = [ $_[0], $_[1] ]; | ||
214 | } else { | ||||
215 | ($p, $k) = $m->__set_path( @_ ); | ||||
216 | } | ||||
217 | 19958 | 4.19ms | return unless defined $p && defined $k; | ||
218 | 19958 | 7.02ms | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||
219 | 19958 | 5.29ms | $m->__set_path_node( $p, $l, @_ ) unless exists $p->[-1]->{ $l }; | ||
220 | 19958 | 3.03ms | if (($f & _MULTI)) { | ||
221 | $p->[-1]->{ $l }->[ _nm ]->{ $id }->{ $attr } = $val; | ||||
222 | } else { | ||||
223 | # Extend the node if it is a simple id node. | ||||
224 | 19958 | 20.6ms | $p->[-1]->{ $l } = [ $p->[-1]->{ $l }, 1 ] unless ref $p->[-1]->{ $l }; | ||
225 | 19958 | 26.2ms | $p->[-1]->{ $l }->[ _na ]->{ $attr } = $val; | ||
226 | } | ||||
227 | 19958 | 63.7ms | return $val; | ||
228 | } | ||||
229 | |||||
230 | sub _get_path_attrs { | ||||
231 | my $m = shift; | ||||
232 | my $f = $m->[ _f ]; | ||||
233 | my $id = pop if ($f & _MULTI); | ||||
234 | @_ = sort @_ if ($f & _UNORD); | ||||
235 | $m->__attr( \@_ ); | ||||
236 | if (($f & _MULTI)) { | ||||
237 | my ($p, $k) = $m->__has_path( @_ ); | ||||
238 | return unless defined $p && defined $k; | ||||
239 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
240 | $p->[-1]->{ $l }->[ _nm ]->{ $id }; | ||||
241 | } else { | ||||
242 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
243 | return unless $e; | ||||
244 | return $n->[ _na ] if ref $n && $#$n == _na; | ||||
245 | return; | ||||
246 | } | ||||
247 | } | ||||
248 | |||||
249 | # spent 146ms (60.5+86.0) within Graph::AdjacencyMap::_get_path_attr which was called 5007 times, avg 29µs/call:
# 5007 times (60.5ms+86.0ms) by Graph::get_edge_attribute at line 1571 of Graph.pm, avg 29µs/call | ||||
250 | 5007 | 724µs | my $m = shift; | ||
251 | 5007 | 840µs | my $f = $m->[ _f ]; | ||
252 | 5007 | 1.10ms | my $attr = pop; | ||
253 | 5007 | 664µs | my $id = pop if ($f & _MULTI); | ||
254 | 5007 | 11.8ms | 5007 | 3.55ms | @_ = sort @_ if ($f & _UNORD); # spent 3.55ms making 5007 calls to Graph::AdjacencyMap::CORE:sort, avg 710ns/call |
255 | 5007 | 6.71ms | 5007 | 33.6ms | $m->__attr( \@_ ); # spent 33.6ms making 5007 calls to Graph::AdjacencyMap::Heavy::__attr, avg 7µs/call |
256 | 5007 | 1.07ms | if (($f & _MULTI)) { | ||
257 | my ($p, $k) = $m->__has_path( @_ ); | ||||
258 | return unless defined $p && defined $k; | ||||
259 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
260 | return $p->[-1]->{ $l }->[ _nm ]->{ $id }->{ $attr }; | ||||
261 | } else { | ||||
262 | 5007 | 13.0ms | 5007 | 48.8ms | my ($e, $n) = $m->__get_path_node( @_ ); # spent 48.8ms making 5007 calls to Graph::AdjacencyMap::__get_path_node, avg 10µs/call |
263 | 5007 | 566µs | return undef unless $e; | ||
264 | 5007 | 20.4ms | return ref $n && $#$n == _na ? $n->[ _na ]->{ $attr } : undef; | ||
265 | } | ||||
266 | } | ||||
267 | |||||
268 | sub _get_path_attr_names { | ||||
269 | my $m = shift; | ||||
270 | my $f = $m->[ _f ]; | ||||
271 | my $id = pop if ($f & _MULTI); | ||||
272 | @_ = sort @_ if ($f & _UNORD); | ||||
273 | $m->__attr( \@_ ); | ||||
274 | if (($f & _MULTI)) { | ||||
275 | my ($p, $k) = $m->__has_path( @_ ); | ||||
276 | return unless defined $p && defined $k; | ||||
277 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
278 | keys %{ $p->[-1]->{ $l }->[ _nm ]->{ $id } }; | ||||
279 | } else { | ||||
280 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
281 | return undef unless $e; | ||||
282 | return keys %{ $n->[ _na ] } if ref $n && $#$n == _na; | ||||
283 | return; | ||||
284 | } | ||||
285 | } | ||||
286 | |||||
287 | sub _get_path_attr_values { | ||||
288 | my $m = shift; | ||||
289 | my $f = $m->[ _f ]; | ||||
290 | my $id = pop if ($f & _MULTI); | ||||
291 | @_ = sort @_ if ($f & _UNORD); | ||||
292 | $m->__attr( \@_ ); | ||||
293 | if (($f & _MULTI)) { | ||||
294 | my ($p, $k) = $m->__has_path( @_ ); | ||||
295 | return unless defined $p && defined $k; | ||||
296 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
297 | values %{ $p->[-1]->{ $l }->[ _nm ]->{ $id } }; | ||||
298 | } else { | ||||
299 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
300 | return undef unless $e; | ||||
301 | return values %{ $n->[ _na ] } if ref $n && $#$n == _na; | ||||
302 | return; | ||||
303 | } | ||||
304 | } | ||||
305 | |||||
306 | sub _del_path_attrs { | ||||
307 | my $m = shift; | ||||
308 | my $f = $m->[ _f ]; | ||||
309 | my $id = pop if ($f & _MULTI); | ||||
310 | @_ = sort @_ if ($f & _UNORD); | ||||
311 | $m->__attr( \@_ ); | ||||
312 | if (($f & _MULTI)) { | ||||
313 | my ($p, $k) = $m->__has_path( @_ ); | ||||
314 | return unless defined $p && defined $k; | ||||
315 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
316 | delete $p->[-1]->{ $l }->[ _nm ]->{ $id }; | ||||
317 | unless (keys %{ $p->[-1]->{ $l }->[ _nm ] } || | ||||
318 | (defined $p->[-1]->{ $l }->[ _na ] && | ||||
319 | keys %{ $p->[-1]->{ $l }->[ _na ] })) { | ||||
320 | delete $p->[-1]->{ $l }; | ||||
321 | } | ||||
322 | } else { | ||||
323 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
324 | return undef unless $e; | ||||
325 | if (ref $n) { | ||||
326 | $e = _na == $#$n && keys %{ $n->[ _na ] } ? 1 : 0; | ||||
327 | $#$n = _na - 1; | ||||
328 | return $e; | ||||
329 | } else { | ||||
330 | return 0; | ||||
331 | } | ||||
332 | } | ||||
333 | } | ||||
334 | |||||
335 | sub _del_path_attr { | ||||
336 | my $m = shift; | ||||
337 | my $f = $m->[ _f ]; | ||||
338 | my $attr = pop; | ||||
339 | my $id = pop if ($f & _MULTI); | ||||
340 | @_ = sort @_ if ($f & _UNORD); | ||||
341 | $m->__attr( \@_ ); | ||||
342 | if (($f & _MULTI)) { | ||||
343 | my ($p, $k) = $m->__has_path( @_ ); | ||||
344 | return unless defined $p && defined $k; | ||||
345 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
346 | delete $p->[-1]->{ $l }->[ _nm ]->{ $id }->{ $attr }; | ||||
347 | $m->_del_path_attrs( @_, $id ) | ||||
348 | unless keys %{ $p->[-1]->{ $l }->[ _nm ]->{ $id } }; | ||||
349 | } else { | ||||
350 | my ($e, $n) = $m->__get_path_node( @_ ); | ||||
351 | return undef unless $e; | ||||
352 | if (ref $n && $#$n == _na && exists $n->[ _na ]->{ $attr }) { | ||||
353 | delete $n->[ _na ]->{ $attr }; | ||||
354 | return 1; | ||||
355 | } else { | ||||
356 | return 0; | ||||
357 | } | ||||
358 | } | ||||
359 | } | ||||
360 | |||||
361 | 31 | 74µs | # spent 66µs within Graph::AdjacencyMap::_is_COUNT which was called 31 times, avg 2µs/call:
# 31 times (66µs+0s) by Graph::countedged at line 337 of Graph.pm, avg 2µs/call | ||
362 | 59852 | 105ms | # spent 53.1ms within Graph::AdjacencyMap::_is_MULTI which was called 59852 times, avg 887ns/call:
# 59852 times (53.1ms+0s) by Graph::multiedged at line 338 of Graph.pm, avg 887ns/call | ||
363 | sub _is_HYPER { $_[0]->[ _f ] & _HYPER } | ||||
364 | 24952 | 47.8ms | # spent 27.1ms within Graph::AdjacencyMap::_is_UNORD which was called 24952 times, avg 1µs/call:
# 24914 times (27.1ms+0s) by Graph::omniedged at line 340 of Graph.pm, avg 1µs/call
# 38 times (56µs+0s) by Graph::directed at line 345 of Graph.pm, avg 1µs/call | ||
365 | sub _is_UNIQ { $_[0]->[ _f ] & _UNIQ } | ||||
366 | sub _is_REF { $_[0]->[ _f ] & _REF } | ||||
367 | sub _is_STR { $_[0]->[ _f ] & _STR } | ||||
368 | |||||
369 | sub __arg { | ||||
370 | my $m = shift; | ||||
371 | my $f = $m->[ _f ]; | ||||
372 | my @a = @{$_[0]}; | ||||
373 | if ($f & _UNIQ) { | ||||
374 | my %u; | ||||
375 | if ($f & _UNORD) { | ||||
376 | @u{ @a } = @a; | ||||
377 | @a = values %u; | ||||
378 | } else { | ||||
379 | my @u; | ||||
380 | for my $e (@a) { | ||||
381 | push @u, $e if $u{$e}++ == 0; | ||||
382 | } | ||||
383 | @a = @u; | ||||
384 | } | ||||
385 | } | ||||
386 | # Alphabetic or numeric sort, does not matter as long as it unifies. | ||||
387 | @{$_[0]} = ($f & _UNORD) ? sort @a : @a; | ||||
388 | } | ||||
389 | |||||
390 | # spent 1.42s (381ms+1.04) within Graph::AdjacencyMap::_successors which was called 24876 times, avg 57µs/call:
# 24876 times (381ms+1.04s) by Graph::successors at line 863 of Graph.pm, avg 57µs/call | ||||
391 | 24876 | 3.03ms | my $E = shift; | ||
392 | 24876 | 1.77ms | my $g = shift; | ||
393 | 24876 | 5.20ms | my $V = $g->[ _V ]; | ||
394 | 74913 | 118ms | 24876 | 45.3ms | map { my @v = @{ $_->[ 1 ] }; # spent 45.3ms making 24876 calls to Graph::_edges_from, avg 2µs/call |
395 | 50037 | 10.9ms | shift @v; | ||
396 | 100074 | 94.2ms | 50037 | 136ms | map { $V->_get_id_path($_) } @v } $g->_edges_from( @_ ); # spent 136ms making 50037 calls to Graph::AdjacencyMap::Light::_get_id_path, avg 3µs/call |
397 | } | ||||
398 | |||||
399 | sub _predecessors { | ||||
400 | my $E = shift; | ||||
401 | my $g = shift; | ||||
402 | my $V = $g->[ _V ]; | ||||
403 | if (wantarray) { | ||||
404 | map { my @v = @{ $_->[ 1 ] }; | ||||
405 | pop @v; | ||||
406 | map { $V->_get_id_path($_) } @v } $g->_edges_to( @_ ); | ||||
407 | } else { | ||||
408 | return $g->_edges_to( @_ ); | ||||
409 | } | ||||
410 | } | ||||
411 | |||||
412 | 1 | 20µs | 1; | ||
413 | __END__ | ||||
# spent 27.1ms within Graph::AdjacencyMap::CORE:sort which was called 49930 times, avg 543ns/call:
# 19958 times (14.6ms+0s) by Graph::AdjacencyMap::_set_path_attr at line 205, avg 730ns/call
# 19958 times (7.19ms+0s) by Graph::AdjacencyMap::_set_path_attr at line 209, avg 360ns/call
# 5007 times (3.55ms+0s) by Graph::AdjacencyMap::_get_path_attr at line 254, avg 710ns/call
# 5007 times (1.79ms+0s) by Graph::AdjacencyMap::__get_path_node at line 112, avg 357ns/call |