Filename | /home/s1/perl5/perlbrew/perls/perl-5.22.1/lib/site_perl/5.22.1/Data/Graph/Util.pm |
Statements | Executed 185 statements in 595µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 78µs | 78µs | _toposort | Data::Graph::Util::
1 | 1 | 1 | 30µs | 30µs | BEGIN@6 | Data::Graph::Util::
1 | 1 | 1 | 10µs | 14µs | BEGIN@7 | Data::Graph::Util::
1 | 1 | 1 | 10µs | 18µs | BEGIN@8 | Data::Graph::Util::
1 | 1 | 1 | 10µs | 20µs | BEGIN@10 | Data::Graph::Util::
1 | 1 | 1 | 10µs | 26µs | BEGIN@42 | Data::Graph::Util::
1 | 1 | 1 | 9µs | 87µs | toposort | Data::Graph::Util::
0 | 0 | 0 | 0s | 0s | is_acyclic | Data::Graph::Util::
0 | 0 | 0 | 0s | 0s | is_cyclic | Data::Graph::Util::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Data::Graph::Util; | ||||
2 | |||||
3 | 1 | 500ns | our $DATE = '2016-06-24'; # DATE | ||
4 | 1 | 100ns | our $VERSION = '0.002'; # VERSION | ||
5 | |||||
6 | 2 | 54µs | 1 | 30µs | # spent 30µs within Data::Graph::Util::BEGIN@6 which was called:
# once (30µs+0s) by DateTime::Format::Alami::new at line 6 # spent 30µs making 1 call to Data::Graph::Util::BEGIN@6 |
7 | 2 | 27µs | 2 | 18µs | # spent 14µs (10+4) within Data::Graph::Util::BEGIN@7 which was called:
# once (10µs+4µs) by DateTime::Format::Alami::new at line 7 # spent 14µs making 1 call to Data::Graph::Util::BEGIN@7
# spent 4µs making 1 call to strict::import |
8 | 2 | 30µs | 2 | 27µs | # spent 18µs (10+9) within Data::Graph::Util::BEGIN@8 which was called:
# once (10µs+9µs) by DateTime::Format::Alami::new at line 8 # spent 18µs making 1 call to Data::Graph::Util::BEGIN@8
# spent 9µs making 1 call to warnings::import |
9 | |||||
10 | 2 | 166µs | 2 | 29µs | # spent 20µs (10+10) within Data::Graph::Util::BEGIN@10 which was called:
# once (10µs+10µs) by DateTime::Format::Alami::new at line 10 # spent 20µs making 1 call to Data::Graph::Util::BEGIN@10
# spent 10µs making 1 call to Exporter::import |
11 | 1 | 1µs | our @EXPORT_OK = qw(toposort is_cyclic is_acyclic); | ||
12 | |||||
13 | # spent 78µs within Data::Graph::Util::_toposort which was called:
# once (78µs+0s) by Data::Graph::Util::toposort at line 60 | ||||
14 | 1 | 300ns | my $graph = shift; | ||
15 | |||||
16 | # this is the Kahn algorithm, ref: | ||||
17 | # https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm | ||||
18 | |||||
19 | 1 | 200ns | my %in_degree; | ||
20 | 1 | 2µs | for my $k (keys %$graph) { | ||
21 | 8 | 3µs | $in_degree{$k} //= 0; | ||
22 | 33 | 15µs | for (@{ $graph->{$k} }) { $in_degree{$_}++ } | ||
23 | } | ||||
24 | |||||
25 | # collect nodes with no incoming edges (in_degree = 0) | ||||
26 | 1 | 200ns | my @S; | ||
27 | 24 | 11µs | for (keys %in_degree) { unshift @S, $_ if $in_degree{$_} == 0 } | ||
28 | |||||
29 | 1 | 100ns | my @L; | ||
30 | 1 | 400ns | while (@S) { | ||
31 | 23 | 4µs | my $n = pop @S; | ||
32 | 23 | 6µs | push @L, $n; | ||
33 | 23 | 18µs | for my $m (@{ $graph->{$n} }) { | ||
34 | 25 | 14µs | if (--$in_degree{$m} == 0) { | ||
35 | unshift @S, $m; | ||||
36 | } | ||||
37 | } | ||||
38 | } | ||||
39 | |||||
40 | 1 | 600ns | if (@L == keys(%$graph)) { | ||
41 | 1 | 300ns | if (@_) { | ||
42 | 2 | 223µs | 2 | 42µs | # spent 26µs (10+16) within Data::Graph::Util::BEGIN@42 which was called:
# once (10µs+16µs) by DateTime::Format::Alami::new at line 42 # spent 26µs making 1 call to Data::Graph::Util::BEGIN@42
# spent 16µs making 1 call to warnings::unimport |
43 | # user specifies a list to be sorted according to @L. this is like | ||||
44 | # Sort::ByExample but we implement it ourselves to avoid dependency. | ||||
45 | my %pos; | ||||
46 | for (0..$#L) { $pos{$L[$_]} = $_+1 } | ||||
47 | return (0, [ | ||||
48 | sort { ($pos{$a} || @L+1) <=> ($pos{$b} || @L+1) } @{$_[0]} | ||||
49 | ]); | ||||
50 | } else { | ||||
51 | 1 | 6µs | return (0, \@L); | ||
52 | } | ||||
53 | } else { | ||||
54 | # there is a cycle | ||||
55 | return (1, \@L); | ||||
56 | } | ||||
57 | } | ||||
58 | |||||
59 | # spent 87µs (9+78) within Data::Graph::Util::toposort which was called:
# once (9µs+78µs) by DateTime::Format::Alami::new at line 84 of lib/DateTime/Format/Alami.pm | ||||
60 | 1 | 1µs | 1 | 78µs | my ($err, $res) = _toposort(@_); # spent 78µs making 1 call to Data::Graph::Util::_toposort |
61 | 1 | 200ns | die "Can't toposort(), graph is cyclic" if $err; | ||
62 | 1 | 6µs | @$res; | ||
63 | } | ||||
64 | |||||
65 | sub is_cyclic { | ||||
66 | my ($err, $res) = _toposort(@_); | ||||
67 | $err; | ||||
68 | } | ||||
69 | |||||
70 | sub is_acyclic { | ||||
71 | my ($err, $res) = _toposort(@_); | ||||
72 | !$err; | ||||
73 | } | ||||
74 | |||||
75 | 1 | 4µs | 1; | ||
76 | # ABSTRACT: Utilities related to graph data structure | ||||
77 | |||||
78 | __END__ |