Profile of Test/Deep/Set.pm

← Index
NYTProf Performance Profile «line view»
For t/optimization.t
Run on Thu Jan 8 22:47:42 2015
Reported on Thu Jan 8 22:48:06 2015

Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Test/Deep/Set.pm
Statements | Executed 91 statements in 963µs

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 644µs | 835µs | Test::Deep::Set::::BEGIN@6Test::Deep::Set::BEGIN@6
2 | 1 | 1 | 70µs | 17.3ms | Test::Deep::Set::::descendTest::Deep::Set::descend
2 | 1 | 1 | 33µs | 36µs | Test::Deep::Set::::addTest::Deep::Set::add
2 | 1 | 1 | 19µs | 55µs | Test::Deep::Set::::initTest::Deep::Set::init
1 | 1 | 1 | 16µs | 34µs | Test::Deep::::BEGIN@1.10 Test::Deep::BEGIN@1.10
1 | 1 | 1 | 11µs | 17µs | Test::Deep::::BEGIN@2.11 Test::Deep::BEGIN@2.11
0 | 0 | 0 | 0s | 0s | Test::Deep::Set::::compareTest::Deep::Set::compare
0 | 0 | 0 | 0s | 0s | Test::Deep::Set::::diagnosticsTest::Deep::Set::diagnostics
0 | 0 | 0 | 0s | 0s | Test::Deep::Set::::nice_listTest::Deep::Set::nice_list

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 | 2 | 30µs | 2 | 52µs | # spent 34µs (16+18) within Test::Deep::BEGIN@1.10 which was called: # once (16µs+18µs) by Test::Deep::bag at line 1 use strict; # spent 34µs making 1 call to Test::Deep::BEGIN@1.10 # spent 18µs making 1 call to strict::import
2 | 2 | 33µs | 2 | 23µs | # spent 17µs (11+6) within Test::Deep::BEGIN@2.11 which was called: # once (11µs+6µs) by Test::Deep::bag at line 2 use warnings; # spent 17µs making 1 call to Test::Deep::BEGIN@2.11 # spent 6µs making 1 call to warnings::import
3 |  |  |  |  |
4 |  |  |  |  | package Test::Deep::Set;
5 |  |  |  |  |
6 | 2 | 773µs | 2 | 857µs | # spent 835µs (644+191) within Test::Deep::Set::BEGIN@6 which was called: # once (644µs+191µs) by Test::Deep::bag at line 6 use Test::Deep::Cmp; # spent 835µs making 1 call to Test::Deep::Set::BEGIN@6 # spent 22µs making 1 call to Test::Deep::Cmp::import
7 |  |  |  |  |
8 |  |  |  |  | sub init
9 |  |  |  |  | # spent 55µs (19+36) within Test::Deep::Set::init which was called 2 times, avg 28µs/call: # 2 times (19µs+36µs) by Test::Deep::Cmp::new at line 33 of Test/Deep/Cmp.pm, avg 28µs/call {
10 | 2 | 1µs |  |  | my $self = shift;
11 |  |  |  |  |
12 | 2 | 4µs |  |  | $self->{IgnoreDupes} = shift;
13 | 2 | 2µs |  |  | $self->{SubSup} = shift;
14 |  |  |  |  |
15 | 2 | 2µs |  |  | $self->{val} = [];
16 |  |  |  |  |
17 | 2 | 10µs | 2 | 36µs | $self->add(@_); # spent 36µs making 2 calls to Test::Deep::Set::add, avg 18µs/call
18 |  |  |  |  | }
19 |  |  |  |  |
20 |  |  |  |  | sub descend
21 |  |  |  |  | # spent 17.3ms (70µs+17.2) within Test::Deep::Set::descend which was called 2 times, avg 8.65ms/call: # 2 times (70µs+17.2ms) by Test::Deep::descend at line 344 of Test/Deep.pm, avg 8.65ms/call {
22 | 2 | 800ns |  |  | my $self = shift;
23 | 2 | 600ns |  |  | my $d1 = shift;
24 |  |  |  |  |
25 | 2 | 2µs |  |  | my $d2 = $self->{val};
26 |  |  |  |  |
27 | 2 | 1µs |  |  | my $IgnoreDupes = $self->{IgnoreDupes};
28 |  |  |  |  |
29 | 2 | 11µs | 2 | 33µs | my $data = $self->data; # spent 33µs making 2 calls to Test::Deep::Cmp::data, avg 16µs/call
30 |  |  |  |  |
31 | 2 | 2µs |  |  | my $SubSup = $self->{SubSup};
32 |  |  |  |  |
33 | 2 | 2µs |  |  | my $type = $IgnoreDupes ? "Set" : "Bag";
34 |  |  |  |  |
35 | 2 | 500ns |  |  | my $diag;
36 |  |  |  |  |
37 | 2 | 2µs |  |  | if (ref $d1 ne 'ARRAY')
38 |  |  |  |  | {
39 |  |  |  |  | my $got = Test::Deep::render_val($d1);
40 |  |  |  |  | $diag = <<EOM;
41 |  |  |  |  | got : $got
42 |  |  |  |  | expect : An array to use as a $type
43 |  |  |  |  | EOM
44 |  |  |  |  | }
45 |  |  |  |  |
46 | 2 | 2µs |  |  | if (not $diag)
47 |  |  |  |  | {
48 | 2 | 4µs |  |  | my @got = @$d1;
49 | 2 | 600ns |  |  | my @missing;
50 | 2 | 3µs |  |  | foreach my $expect (@$d2)
51 |  |  |  |  | {
52 | 2 | 700ns |  |  | my $found = 0;
53 |  |  |  |  |
54 | 2 | 4µs |  |  | for (my $i = $#got; $i >= 0; $i--)
55 |  |  |  |  | {
56 | 2 | 7µs | 2 | 17.2ms | if (Test::Deep::eq_deeply_cache($got[$i], $expect)) # spent 17.2ms making 2 calls to Test::Deep::eq_deeply_cache, avg 8.59ms/call
57 |  |  |  |  | {
58 | 2 | 1µs |  |  | $found = 1;
59 | 2 | 3µs |  |  | splice(@got, $i, 1);
60 |  |  |  |  |
61 | 2 | 3µs |  |  | last unless $IgnoreDupes;
62 |  |  |  |  | }
63 |  |  |  |  | }
64 |  |  |  |  |
65 | 2 | 2µs |  |  | push(@missing, $expect) unless $found;
66 |  |  |  |  | }
67 |  |  |  |  |
68 |  |  |  |  |
69 | 2 | 800ns |  |  | my @diags;
70 | 2 | 1µs |  |  | if (@missing and $SubSup ne "sub")
71 |  |  |  |  | {
72 |  |  |  |  | push(@diags, "Missing: ".nice_list(\@missing));
73 |  |  |  |  | }
74 |  |  |  |  |
75 | 2 | 500ns |  |  | if (@got and $SubSup ne "sup")
76 |  |  |  |  | {
77 |  |  |  |  | my $got = __PACKAGE__->new($IgnoreDupes, "", @got);
78 |  |  |  |  | push(@diags, "Extra: ".nice_list($got->{val}));
79 |  |  |  |  | }
80 |  |  |  |  |
81 | 2 | 4µs |  |  | $diag = join("\n", @diags);
82 |  |  |  |  | }
83 |  |  |  |  |
84 | 2 | 900ns |  |  | if ($diag)
85 |  |  |  |  | {
86 |  |  |  |  | $data->{diag} = $diag;
87 |  |  |  |  |
88 |  |  |  |  | return 0;
89 |  |  |  |  | }
90 |  |  |  |  | else
91 |  |  |  |  | {
92 | 2 | 8µs |  |  | return 1;
93 |  |  |  |  | }
94 |  |  |  |  | }
95 |  |  |  |  |
96 |  |  |  |  | sub diagnostics
97 |  |  |  |  | {
98 |  |  |  |  | my $self = shift;
99 |  |  |  |  | my ($where, $last) = @_;
100 |  |  |  |  |
101 |  |  |  |  | my $type = $self->{IgnoreDupes} ? "Set" : "Bag";
102 |  |  |  |  | $type = "Sub$type" if $self->{SubSup} eq "sub";
103 |  |  |  |  | $type = "Super$type" if $self->{SubSup} eq "sup";
104 |  |  |  |  |
105 |  |  |  |  | my $error = $last->{diag};
106 |  |  |  |  | my $diag = <<EOM;
107 |  |  |  |  | Comparing $where as a $type
108 |  |  |  |  | $error
109 |  |  |  |  | EOM
110 |  |  |  |  |
111 |  |  |  |  | return $diag;
112 |  |  |  |  | }
113 |  |  |  |  |
114 |  |  |  |  | sub add
115 |  |  |  |  | # spent 36µs (33+3) within Test::Deep::Set::add which was called 2 times, avg 18µs/call: # 2 times (33µs+3µs) by Test::Deep::Set::init at line 17, avg 18µs/call {
116 |  |  |  |  | # this takes an array.
117 |  |  |  |  |
118 |  |  |  |  | # For each element A of the array, it looks for an element, B, already in
119 |  |  |  |  | # the set which are deeply equal to A. If no matching B is found then A is
120 |  |  |  |  | # added to the set. If a B is found and IgnoreDupes is true, then A will
121 |  |  |  |  | # be discarded, if IgnoreDupes is false, then B will be added to the set
122 |  |  |  |  | # again.
123 |  |  |  |  |
124 | 2 | 700ns |  |  | my $self = shift;
125 |  |  |  |  |
126 | 2 | 2µs |  |  | my @array = @_;
127 |  |  |  |  |
128 | 2 | 1µs |  |  | my $IgnoreDupes = $self->{IgnoreDupes};
129 |  |  |  |  |
130 | 2 | 900ns |  |  | my $already = $self->{val};
131 |  |  |  |  |
132 | 2 | 1µs |  |  | local $Test::Deep::Expects = 1;
133 | 2 | 2µs |  |  | foreach my $new_elem (@array)
134 |  |  |  |  | {
135 | 2 | 500ns |  |  | my $want_push = 1;
136 | 2 | 500ns |  |  | my $push_this = $new_elem;
137 | 2 | 2µs |  |  | foreach my $old_elem (@$already)
138 |  |  |  |  | {
139 |  |  |  |  | if (Test::Deep::eq_deeply($new_elem, $old_elem))
140 |  |  |  |  | {
141 |  |  |  |  | $push_this = $old_elem;
142 |  |  |  |  | $want_push = ! $IgnoreDupes;
143 |  |  |  |  | last;
144 |  |  |  |  | }
145 |  |  |  |  | }
146 | 2 | 3µs |  |  | push(@$already, $push_this) if $want_push;
147 |  |  |  |  | }
148 |  |  |  |  |
149 |  |  |  |  | # so we can compare 2 Test::Deep::Set objects using array comparison
150 |  |  |  |  |
151 | 2 | 24µs | 2 | 3µs | @$already = sort {(defined $a ? $a : "") cmp (defined $b ? $b : "")} @$already; # spent 3µs making 2 calls to Test::Deep::Set::CORE:sort, avg 1µs/call
152 |  |  |  |  | }
153 |  |  |  |  |
154 |  |  |  |  | sub nice_list
155 |  |  |  |  | {
156 |  |  |  |  | my $list = shift;
157 |  |  |  |  |
158 |  |  |  |  | my @scalars = grep ! ref $_, @$list;
159 |  |  |  |  | my $refs = grep ref $_, @$list;
160 |  |  |  |  |
161 |  |  |  |  | my @ref_string = "$refs reference" if $refs;
162 |  |  |  |  | $ref_string[0] .= "s" if $refs > 1;
163 |  |  |  |  |
164 |  |  |  |  | # sort them so we can predict the diagnostic output
165 |  |  |  |  |
166 |  |  |  |  | return join(", ",
167 |  |  |  |  | (map {Test::Deep::render_val($_)} sort {(defined $a ? $a : "") cmp (defined $b ? $b : "")} @scalars),
168 |  |  |  |  | @ref_string
169 |  |  |  |  | );
170 |  |  |  |  | }
171 |  |  |  |  |
172 |  |  |  |  | sub compare
173 |  |  |  |  | {
174 |  |  |  |  | my $self = shift;
175 |  |  |  |  |
176 |  |  |  |  | my $other = shift;
177 |  |  |  |  |
178 |  |  |  |  | return 0 if $self->{IgnoreDupes} != $other->{IgnoreDupes};
179 |  |  |  |  |
180 |  |  |  |  | # this works (kind of) because the arrays are sorted
181 |  |  |  |  |
182 |  |  |  |  | return Test::Deep::descend($self->{val}, $other->{val});
183 |  |  |  |  | }
184 |  |  |  |  |
185 | 1 | 3µs |  |  | 1;