Profile of Data/Graph/Util.pm

← Index
NYTProf Performance Profile «line view»
For -e
Run on Thu Jun 30 16:34:56 2016
Reported on Thu Jun 30 16:35:08 2016

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

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 78µs | 78µs | Data::Graph::Util::::_toposortData::Graph::Util::_toposort
1 | 1 | 1 | 30µs | 30µs | Data::Graph::Util::::BEGIN@6Data::Graph::Util::BEGIN@6
1 | 1 | 1 | 10µs | 14µs | Data::Graph::Util::::BEGIN@7Data::Graph::Util::BEGIN@7
1 | 1 | 1 | 10µs | 18µs | Data::Graph::Util::::BEGIN@8Data::Graph::Util::BEGIN@8
1 | 1 | 1 | 10µs | 20µs | Data::Graph::Util::::BEGIN@10Data::Graph::Util::BEGIN@10
1 | 1 | 1 | 10µs | 26µs | Data::Graph::Util::::BEGIN@42Data::Graph::Util::BEGIN@42
1 | 1 | 1 | 9µs | 87µs | Data::Graph::Util::::toposortData::Graph::Util::toposort
0 | 0 | 0 | 0s | 0s | Data::Graph::Util::::is_acyclicData::Graph::Util::is_acyclic
0 | 0 | 0 | 0s | 0s | Data::Graph::Util::::is_cyclicData::Graph::Util::is_cyclic

Call graph for these subroutines as a Graphviz dot language file.

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 use 5.010001; # 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 use strict; # 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 use warnings; # 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 use Exporter qw(import); # 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 sub _toposort {
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 no warnings 'uninitialized'; # 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 sub toposort {
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__