| 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 | Graph::AdjacencyMap::_successors |
| 19958 | 1 | 1 | 341ms | 505ms | Graph::AdjacencyMap::_set_path_attr |
| 5007 | 1 | 1 | 60.5ms | 146ms | Graph::AdjacencyMap::_get_path_attr |
| 59852 | 1 | 1 | 53.1ms | 53.1ms | Graph::AdjacencyMap::_is_MULTI |
| 14965 | 1 | 1 | 48.0ms | 48.0ms | Graph::AdjacencyMap::_new_node |
| 5007 | 1 | 1 | 47.0ms | 48.8ms | Graph::AdjacencyMap::__get_path_node |
| 24952 | 2 | 1 | 27.1ms | 27.1ms | Graph::AdjacencyMap::_is_UNORD |
| 49930 | 4 | 1 | 27.1ms | 27.1ms | Graph::AdjacencyMap::CORE:sort (opcode) |
| 4993 | 1 | 1 | 9.67ms | 9.67ms | Graph::AdjacencyMap::_inc_node |
| 67 | 1 | 1 | 303µs | 303µs | Graph::AdjacencyMap::_new |
| 67 | 1 | 1 | 168µs | 168µs | Graph::AdjacencyMap::_ids |
| 31 | 1 | 1 | 66µs | 66µs | Graph::AdjacencyMap::_is_COUNT |
| 1 | 1 | 1 | 12µs | 24µs | Graph::AdjacencyMap::BEGIN@3 |
| 1 | 1 | 1 | 8µs | 59µs | Graph::AdjacencyMap::BEGIN@6 |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_GEN_ID |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::__arg |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_del_id |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_del_path_attr |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_del_path_attrs |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_dump |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_get_path_attr_names |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_get_path_attr_values |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_get_path_attrs |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_has_path_attr |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_has_path_attrs |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_is_HYPER |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_is_REF |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_is_STR |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_is_UNIQ |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_predecessors |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::_set_path_attrs |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::get_multi_ids |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::has_paths |
| 0 | 0 | 0 | 0s | 0s | Graph::AdjacencyMap::set_path_by_multi_id |
| 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 | 201 | 350µs | my $class = shift; | ||
| 52 | my $map = bless [ 0, @_ ], $class; | ||||
| 53 | 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 | 134 | 225µs | my $m = shift; | ||
| 58 | 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 | 74825 | 49.4ms | my ($m, $n, $id) = @_; | ||
| 79 | my $f = $m->[ _f ]; | ||||
| 80 | my $i = $m->[ _n ]++; | ||||
| 81 | 14965 | 3.89ms | 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 | $$n = $i; | ||||
| 88 | } | ||||
| 89 | 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 | 19972 | 12.5ms | my ($m, $n, $id) = @_; | ||
| 94 | my $f = $m->[ _f ]; | ||||
| 95 | 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 | 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 | 40056 | 35.8ms | my $m = shift; | ||
| 110 | my ($p, $k); | ||||
| 111 | my $f = $m->[ _f ]; | ||||
| 112 | 5007 | 1.79ms | @_ = sort @_ if ($f & _UNORD); # spent 1.79ms making 5007 calls to Graph::AdjacencyMap::CORE:sort, avg 357ns/call | ||
| 113 | 15021 | 12.1ms | if ($m->[ _a ] == 2 && @_ == 2 && !($f & (_HYPER|_REF|_UNIQ))) { # Fast path. | ||
| 114 | return unless exists $m->[ _s ]->{ $_[0] }; | ||||
| 115 | $p = [ $m->[ _s ], $m->[ _s ]->{ $_[0] } ]; | ||||
| 116 | $k = [ $_[0], $_[1] ]; | ||||
| 117 | } else { | ||||
| 118 | ($p, $k) = $m->__has_path( @_ ); | ||||
| 119 | } | ||||
| 120 | return unless defined $p && defined $k; | ||||
| 121 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
| 122 | 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 | 319328 | 227ms | my $m = shift; | ||
| 201 | my $f = $m->[ _f ]; | ||||
| 202 | my $val = pop; | ||||
| 203 | my $attr = pop; | ||||
| 204 | my $id = pop if ($f & _MULTI); | ||||
| 205 | 19958 | 14.6ms | @_ = sort @_ if ($f & _UNORD); # spent 14.6ms making 19958 calls to Graph::AdjacencyMap::CORE:sort, avg 730ns/call | ||
| 206 | my ($p, $k); | ||||
| 207 | 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 | push @_, $id if ($f & _MULTI); | ||||
| 209 | 19958 | 7.19ms | @_ = sort @_ if ($f & _UNORD); # spent 7.19ms making 19958 calls to Graph::AdjacencyMap::CORE:sort, avg 360ns/call | ||
| 210 | 59874 | 40.8ms | if ($m->[ _a ] == 2 && @_ == 2 && !($f & (_REF|_UNIQ|_HYPER|_UNIQ))) { | ||
| 211 | $m->[ _s ]->{ $_[0] } ||= { }; | ||||
| 212 | $p = [ $m->[ _s ], $m->[ _s ]->{ $_[0] } ]; | ||||
| 213 | $k = [ $_[0], $_[1] ]; | ||||
| 214 | } else { | ||||
| 215 | ($p, $k) = $m->__set_path( @_ ); | ||||
| 216 | } | ||||
| 217 | return unless defined $p && defined $k; | ||||
| 218 | my $l = defined $k->[-1] ? $k->[-1] : ""; | ||||
| 219 | $m->__set_path_node( $p, $l, @_ ) unless exists $p->[-1]->{ $l }; | ||||
| 220 | 39916 | 46.8ms | 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 | $p->[-1]->{ $l } = [ $p->[-1]->{ $l }, 1 ] unless ref $p->[-1]->{ $l }; | ||||
| 225 | $p->[-1]->{ $l }->[ _na ]->{ $attr } = $val; | ||||
| 226 | } | ||||
| 227 | 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 | 35049 | 22.9ms | my $m = shift; | ||
| 251 | my $f = $m->[ _f ]; | ||||
| 252 | my $attr = pop; | ||||
| 253 | my $id = pop if ($f & _MULTI); | ||||
| 254 | 5007 | 3.55ms | @_ = sort @_ if ($f & _UNORD); # spent 3.55ms making 5007 calls to Graph::AdjacencyMap::CORE:sort, avg 710ns/call | ||
| 255 | 5007 | 33.6ms | $m->__attr( \@_ ); # spent 33.6ms making 5007 calls to Graph::AdjacencyMap::Heavy::__attr, avg 7µs/call | ||
| 256 | 15021 | 33.9ms | 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 | 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 | return undef unless $e; | ||||
| 264 | 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 | 99504 | 78.8ms | my $E = shift; | ||
| 392 | my $g = shift; | ||||
| 393 | my $V = $g->[ _V ]; | ||||
| 394 | 150111 | 103ms | 24876 | 45.3ms | map { my @v = @{ $_->[ 1 ] }; # spent 45.3ms making 24876 calls to Graph::_edges_from, avg 2µs/call |
| 395 | shift @v; | ||||
| 396 | 50037 | 51.6ms | 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 |