Profile of Test/Deep.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:05 2015

Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Test/Deep.pm
Statements | Executed 732 statements in 5.64ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 3.03ms | 3.40ms | Test::Deep::::BEGIN@5Test::Deep::BEGIN@5
10 | 5 | 4 | 1.46ms | 3.01ms | Test::Deep::::__ANON__[:81]Test::Deep::__ANON__[:81]
2 | 1 | 1 | 856µs | 1.95ms | Test::Deep::::bagTest::Deep::bag
46 | 10 | 7 | 644µs | 17.7ms | Test::Deep::::descendTest::Deep::descend (recurses: max depth 4, inclusive time 23.5ms)
1 | 1 | 1 | 515µs | 1.26ms | Test::Deep::::BEGIN@8Test::Deep::BEGIN@8
1 | 1 | 1 | 434µs | 2.35ms | Test::Deep::::BEGIN@7Test::Deep::BEGIN@7
2 | 1 | 1 | 203µs | 18.1ms | Test::Deep::::cmp_detailsTest::Deep::cmp_details
18 | 1 | 1 | 184µs | 1.61ms | Test::Deep::::wrapTest::Deep::wrap
1 | 1 | 1 | 166µs | 248µs | Test::Deep::::BEGIN@9Test::Deep::BEGIN@9
30 | 1 | 1 | 59µs | 59µs | Test::Deep::::CORE:substTest::Deep::CORE:subst (opcode)
2 | 1 | 1 | 50µs | 17.2ms | Test::Deep::::eq_deeply_cacheTest::Deep::eq_deeply_cache
2 | 1 | 1 | 32µs | 36µs | Test::Deep::::class_baseTest::Deep::class_base
2 | 1 | 1 | 31µs | 18.9ms | Test::Deep::::cmp_deeplyTest::Deep::cmp_deeply
2 | 2 | 1 | 29µs | 20.9ms | Test::Deep::::cmp_bagTest::Deep::cmp_bag
1 | 1 | 1 | 15µs | 33µs | Test::Deep::::BEGIN@83Test::Deep::BEGIN@83
1 | 1 | 1 | 14µs | 31µs | main::::BEGIN@1 main::BEGIN@1
1 | 1 | 1 | 13µs | 52µs | Test::Deep::::BEGIN@12Test::Deep::BEGIN@12
1 | 1 | 1 | 10µs | 17µs | main::::BEGIN@2 main::BEGIN@2
0 | 0 | 0 | 0s | 0s | Test::Deep::::builderTest::Deep::builder
0 | 0 | 0 | 0s | 0s | Test::Deep::::cmp_methodsTest::Deep::cmp_methods
0 | 0 | 0 | 0s | 0s | Test::Deep::::cmp_setTest::Deep::cmp_set
0 | 0 | 0 | 0s | 0s | Test::Deep::::deep_diagTest::Deep::deep_diag
0 | 0 | 0 | 0s | 0s | Test::Deep::::eq_deeplyTest::Deep::eq_deeply
0 | 0 | 0 | 0s | 0s | Test::Deep::::isaTest::Deep::isa
0 | 0 | 0 | 0s | 0s | Test::Deep::::noclassTest::Deep::noclass
0 | 0 | 0 | 0s | 0s | Test::Deep::::render_stackTest::Deep::render_stack
0 | 0 | 0 | 0s | 0s | Test::Deep::::render_valTest::Deep::render_val
0 | 0 | 0 | 0s | 0s | Test::Deep::::requireclassTest::Deep::requireclass
0 | 0 | 0 | 0s | 0s | Test::Deep::::setTest::Deep::set
0 | 0 | 0 | 0s | 0s | Test::Deep::::subbagofTest::Deep::subbagof
0 | 0 | 0 | 0s | 0s | Test::Deep::::subhashofTest::Deep::subhashof
0 | 0 | 0 | 0s | 0s | Test::Deep::::subsetofTest::Deep::subsetof
0 | 0 | 0 | 0s | 0s | Test::Deep::::superbagofTest::Deep::superbagof
0 | 0 | 0 | 0s | 0s | Test::Deep::::superhashofTest::Deep::superhashof
0 | 0 | 0 | 0s | 0s | Test::Deep::::supersetofTest::Deep::supersetof

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 | 2 | 33µs | 2 | 48µs | # spent 31µs (14+16) within main::BEGIN@1 which was called: # once (14µs+16µs) by main::BEGIN@7 at line 1 use strict; # spent 31µs making 1 call to main::BEGIN@1 # spent 16µs making 1 call to strict::import
2 | 2 | 36µs | 2 | 24µs | # spent 17µs (10+7) within main::BEGIN@2 which was called: # once (10µs+7µs) by main::BEGIN@7 at line 2 use warnings; # spent 17µs making 1 call to main::BEGIN@2 # spent 7µs making 1 call to warnings::import
3 |  |  |  |  |
4 |  |  |  |  | package Test::Deep;
5 | 2 | 115µs | 2 | 3.47ms | # spent 3.40ms (3.03+373µs) within Test::Deep::BEGIN@5 which was called: # once (3.03ms+373µs) by main::BEGIN@7 at line 5 use Carp qw( confess ); # spent 3.40ms making 1 call to Test::Deep::BEGIN@5 # spent 73µs making 1 call to Exporter::import
6 |  |  |  |  |
7 | 2 | 124µs | 1 | 2.35ms | # spent 2.35ms (434µs+1.91) within Test::Deep::BEGIN@7 which was called: # once (434µs+1.91ms) by main::BEGIN@7 at line 7 use Test::Deep::Cache; # spent 2.35ms making 1 call to Test::Deep::BEGIN@7
8 | 2 | 122µs | 1 | 1.26ms | # spent 1.26ms (515µs+743µs) within Test::Deep::BEGIN@8 which was called: # once (515µs+743µs) by main::BEGIN@7 at line 8 use Test::Deep::Stack; # spent 1.26ms making 1 call to Test::Deep::BEGIN@8
9 | 2 | 127µs | 1 | 248µs | # spent 248µs (166+81) within Test::Deep::BEGIN@9 which was called: # once (166µs+81µs) by main::BEGIN@7 at line 9 use Test::Deep::RegexpVersion; # spent 248µs making 1 call to Test::Deep::BEGIN@9
10 |  |  |  |  |
11 | 1 | 658µs |  |  | require overload;
12 | 2 | 341µs | 2 | 92µs | # spent 52µs (13+39) within Test::Deep::BEGIN@12 which was called: # once (13µs+39µs) by main::BEGIN@7 at line 12 use Scalar::Util; # spent 52µs making 1 call to Test::Deep::BEGIN@12 # spent 39µs making 1 call to Exporter::import
13 |  |  |  |  |
14 | 1 | 200ns |  |  | my $Test;
15 | 1 | 800ns |  |  | unless (defined $Test::Deep::NoTest::NoTest)
16 |  |  |  |  | {
17 |  |  |  |  | # for people who want eq_deeply but not Test::Builder
18 | 1 | 800ns |  |  | require Test::Builder;
19 | 1 | 6µs | 1 | 4µs | $Test = Test::Builder->new; # spent 4µs making 1 call to Test::Builder::new
20 |  |  |  |  | }
21 |  |  |  |  |
22 | 1 | 700ns |  |  | our ($Stack, %Compared, $CompareCache, %WrapCache, $Shallow);
23 |  |  |  |  |
24 | 1 | 500ns |  |  | our $VERSION = '0.112';
25 | 1 | 20µs |  |  | $VERSION = eval $VERSION; # spent 2µs executing statements in string eval
26 |  |  |  |  |
27 | 1 | 700ns |  |  | require Exporter;
28 | 1 | 9µs |  |  | our @ISA = qw( Exporter );
29 |  |  |  |  |
30 | 1 | 400ns |  |  | our $Snobby = 1; # should we compare classes?
31 | 1 | 400ns |  |  | our $Expects = 0; # are we comparing got vs expect or expect vs expect
32 |  |  |  |  |
33 | 1 | 200ns |  |  | our $DNE = \"";
34 | 1 | 12µs | 1 | 5µs | our $DNE_ADDR = Scalar::Util::refaddr($DNE); # spent 5µs making 1 call to Scalar::Util::refaddr
35 |  |  |  |  |
36 |  |  |  |  | # if no sub name is supplied then we use the package name in lower case
37 | 1 | 13µs |  |  | my @constructors = (
38 |  |  |  |  | All => "",
39 |  |  |  |  | Any => "",
40 |  |  |  |  | Array => "",
41 |  |  |  |  | ArrayEach => "array_each",
42 |  |  |  |  | ArrayElementsOnly => "",
43 |  |  |  |  | ArrayLength => "",
44 |  |  |  |  | ArrayLengthOnly => "",
45 |  |  |  |  | Blessed => "",
46 |  |  |  |  | Boolean => "bool",
47 |  |  |  |  | Code => "",
48 |  |  |  |  | Hash => "",
49 |  |  |  |  | HashEach => "hash_each",
50 |  |  |  |  | HashKeys => "",
51 |  |  |  |  | HashKeysOnly => "",
52 |  |  |  |  | Ignore => "",
53 |  |  |  |  | Isa => "Isa",
54 |  |  |  |  | ListMethods => "",
55 |  |  |  |  | Methods => "",
56 |  |  |  |  | Number => "num",
57 |  |  |  |  | Obj => "obj_isa",
58 |  |  |  |  | RefType => "",
59 |  |  |  |  | Regexp => "re",
60 |  |  |  |  | RegexpMatches => "",
61 |  |  |  |  | RegexpOnly => "",
62 |  |  |  |  | RegexpRef => "",
63 |  |  |  |  | RegexpRefOnly => "",
64 |  |  |  |  | ScalarRef => "scalref",
65 |  |  |  |  | ScalarRefOnly => "",
66 |  |  |  |  | Shallow => "",
67 |  |  |  |  | String => "str",
68 |  |  |  |  | );
69 |  |  |  |  |
70 | 1 | 200ns |  |  | my @CONSTRUCTORS_FROM_CLASSES;
71 |  |  |  |  |
72 | 1 | 32µs |  |  | while (my ($pkg, $name) = splice @constructors, 0, 2)
73 |  |  |  |  | {
74 | 30 | 11µs |  |  | $name = lc($pkg) unless $name;
75 | 30 | 15µs |  |  | my $full_pkg = "Test::Deep::$pkg";
76 | 30 | 13µs |  |  | my $file = "$full_pkg.pm";
77 | 30 | 124µs | 30 | 59µs | $file =~ s#::#/#g; # spent 59µs making 30 calls to Test::Deep::CORE:subst, avg 2µs/call
78 |  |  |  |  | # spent 3.01ms (1.46+1.55) within Test::Deep::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Test/Deep.pm:81] which was called 10 times, avg 301µs/call: # 2 times (541µs+812µs) by Test::Deep::wrap at line 378, avg 677µs/call # 2 times (329µs+248µs) by Test::Deep::Ref::test_class at line 17 of Test/Deep/Ref.pm, avg 288µs/call # 2 times (298µs+227µs) by Test::Deep::Ref::test_reftype at line 33 of Test/Deep/Ref.pm, avg 263µs/call # 2 times (280µs+244µs) by Test::Deep::RefType::descend at line 26 of Test/Deep/RefType.pm, avg 262µs/call # 2 times (11µs+17µs) by Test::Deep::Blessed::descend at line 27 of Test/Deep/Blessed.pm, avg 14µs/call my $sub = sub {
79 | 10 | 268µs |  |  | require $file;
80 | 10 | 88µs | 10 | 596µs | return $full_pkg->new(@_); # spent 596µs making 10 calls to Test::Deep::Cmp::new, avg 60µs/call
81 | 30 | 52µs |  |  | };
82 |  |  |  |  | {
83 | 32 | 1.95ms | 2 | 52µs | # spent 33µs (15+19) within Test::Deep::BEGIN@83 which was called: # once (15µs+19µs) by main::BEGIN@7 at line 83 no strict 'refs'; # spent 33µs making 1 call to Test::Deep::BEGIN@83 # spent 19µs making 1 call to strict::unimport
84 | 30 | 51µs |  |  | *{$name} = $sub;
85 |  |  |  |  | }
86 |  |  |  |  |
87 | 30 | 22µs |  |  | push @CONSTRUCTORS_FROM_CLASSES, $name;
88 |  |  |  |  | }
89 |  |  |  |  |
90 |  |  |  |  | {
91 | 2 | 2µs |  |  | our @EXPORT_OK = qw( descend render_stack class_base cmp_details deep_diag );
92 |  |  |  |  |
93 | 1 | 100ns |  |  | our %EXPORT_TAGS;
94 | 1 | 11µs |  |  | $EXPORT_TAGS{v0} = [
95 |  |  |  |  | qw(
96 |  |  |  |  | Isa
97 |  |  |  |  | blessed
98 |  |  |  |  | obj_isa
99 |  |  |  |  |
100 |  |  |  |  | all any array array_each arrayelementsonly arraylength arraylengthonly
101 |  |  |  |  | bag bool cmp_bag cmp_deeply cmp_methods cmp_set code eq_deeply
102 |  |  |  |  | hash hash_each hashkeys hashkeysonly ignore isa listmethods methods
103 |  |  |  |  | noclass num re reftype regexpmatches regexponly regexpref regexprefonly
104 |  |  |  |  | scalarrefonly scalref set shallow str subbagof subhashof subsetof
105 |  |  |  |  | superbagof superhashof supersetof useclass
106 |  |  |  |  | )
107 |  |  |  |  | ];
108 |  |  |  |  |
109 | 1 | 6µs |  |  | $EXPORT_TAGS{v1} = [
110 |  |  |  |  | qw(
111 |  |  |  |  | obj_isa
112 |  |  |  |  |
113 |  |  |  |  | all any array array_each arrayelementsonly arraylength arraylengthonly
114 |  |  |  |  | bag bool cmp_bag cmp_deeply cmp_methods cmp_set code eq_deeply
115 |  |  |  |  | hash hash_each hashkeys hashkeysonly ignore listmethods methods
116 |  |  |  |  | noclass num re reftype regexpmatches regexponly regexpref regexprefonly
117 |  |  |  |  | scalarrefonly scalref set shallow str subbagof subhashof subsetof
118 |  |  |  |  | superbagof superhashof supersetof useclass
119 |  |  |  |  | )
120 |  |  |  |  | ];
121 |  |  |  |  |
122 | 1 | 10µs |  |  | our @EXPORT = @{ $EXPORT_TAGS{ v0 } };
123 |  |  |  |  |
124 | 1 | 8µs |  |  | $EXPORT_TAGS{all} = [ @EXPORT, @EXPORT_OK ];
125 |  |  |  |  | }
126 |  |  |  |  |
127 |  |  |  |  | # this is ugly, I should never have exported a sub called isa now I
128 |  |  |  |  | # have to try figure out if the recipient wanted my isa or if a class
129 |  |  |  |  | # imported us and UNIVERSAL::isa is being called on that class.
130 |  |  |  |  | # Luckily our isa always expects 1 argument and U::isa always expects
131 |  |  |  |  | # 2, so we can figure out (assuming the caller is not buggy).
132 |  |  |  |  | sub isa
133 |  |  |  |  | {
134 |  |  |  |  | if (@_ == 1)
135 |  |  |  |  | {
136 |  |  |  |  | goto &Isa;
137 |  |  |  |  | }
138 |  |  |  |  | else
139 |  |  |  |  | {
140 |  |  |  |  | goto &UNIVERSAL::isa;
141 |  |  |  |  | }
142 |  |  |  |  | }
143 |  |  |  |  |
144 |  |  |  |  | sub cmp_deeply
145 |  |  |  |  | # spent 18.9ms (31µs+18.9) within Test::Deep::cmp_deeply which was called 2 times, avg 9.45ms/call: # 2 times (31µs+18.9ms) by Test::Deep::cmp_bag at line 518, avg 9.45ms/call {
146 | 2 | 3µs |  |  | my ($d1, $d2, $name) = @_;
147 |  |  |  |  |
148 | 2 | 5µs | 2 | 18.1ms | my ($ok, $stack) = cmp_details($d1, $d2); # spent 18.1ms making 2 calls to Test::Deep::cmp_details, avg 9.06ms/call
149 |  |  |  |  |
150 | 2 | 8µs | 2 | 737µs | if (not $Test->ok($ok, $name)) # spent 737µs making 2 calls to Test::Builder::ok, avg 368µs/call
151 |  |  |  |  | {
152 |  |  |  |  | my $diag = deep_diag($stack);
153 |  |  |  |  | $Test->diag($diag);
154 |  |  |  |  | }
155 |  |  |  |  |
156 | 2 | 9µs |  |  | return $ok;
157 |  |  |  |  | }
158 |  |  |  |  |
159 |  |  |  |  | sub cmp_details
160 |  |  |  |  | # spent 18.1ms (203µs+17.9) within Test::Deep::cmp_details which was called 2 times, avg 9.06ms/call: # 2 times (203µs+17.9ms) by Test::Deep::cmp_deeply at line 148, avg 9.06ms/call {
161 | 2 | 1µs |  |  | my ($d1, $d2) = @_;
162 |  |  |  |  |
163 | 2 | 13µs | 2 | 94µs | local $Stack = Test::Deep::Stack->new; # spent 94µs making 2 calls to Test::Deep::MM::new, avg 47µs/call
164 | 2 | 8µs | 2 | 99µs | local $CompareCache = Test::Deep::Cache->new; # spent 99µs making 2 calls to Test::Deep::Cache::new, avg 50µs/call
165 | 2 | 1µs |  |  | local %WrapCache;
166 |  |  |  |  |
167 | 2 | 4µs | 2 | 17.7ms | my $ok = descend($d1, $d2); # spent 17.7ms making 2 calls to Test::Deep::descend, avg 8.86ms/call
168 |  |  |  |  |
169 | 2 | 168µs |  |  | return ($ok, $Stack);
170 |  |  |  |  | }
171 |  |  |  |  |
172 |  |  |  |  | sub eq_deeply
173 |  |  |  |  | {
174 |  |  |  |  | my ($d1, $d2) = @_;
175 |  |  |  |  |
176 |  |  |  |  | my ($ok) = cmp_details($d1, $d2);
177 |  |  |  |  |
178 |  |  |  |  | return $ok
179 |  |  |  |  | }
180 |  |  |  |  |
181 |  |  |  |  | sub eq_deeply_cache
182 |  |  |  |  | # spent 17.2ms (50µs+17.1) within Test::Deep::eq_deeply_cache which was called 2 times, avg 8.59ms/call: # 2 times (50µs+17.1ms) by Test::Deep::Set::descend at line 56 of Test/Deep/Set.pm, avg 8.59ms/call {
183 |  |  |  |  | # this is like cross between eq_deeply and descend(). It doesn't start
184 |  |  |  |  | # with a new $CompareCache but if the comparison fails it will leave
185 |  |  |  |  | # $CompareCache as if nothing happened. However, if the comparison
186 |  |  |  |  | # succeeds then $CompareCache retains all the new information
187 |  |  |  |  |
188 |  |  |  |  | # this allows Set and Bag to handle circular refs
189 |  |  |  |  |
190 | 2 | 2µs |  |  | my ($d1, $d2, $name) = @_;
191 |  |  |  |  |
192 | 2 | 9µs | 2 | 64µs | local $Stack = Test::Deep::Stack->new; # spent 64µs making 2 calls to Test::Deep::MM::new, avg 32µs/call
193 | 2 | 5µs | 2 | 48µs | $CompareCache->local; # spent 48µs making 2 calls to Test::Deep::Cache::local, avg 24µs/call
194 |  |  |  |  |
195 | 2 | 15µs | 2 | 0s | my $ok = descend($d1, $d2); # spent 16.9ms making 2 calls to Test::Deep::descend, avg 8.47ms/call, recursion: max depth 1, sum of overlapping time 16.9ms
196 |  |  |  |  |
197 | 2 | 6µs | 2 | 79µs | $CompareCache->finish($ok); # spent 79µs making 2 calls to Test::Deep::Cache::finish, avg 39µs/call
198 |  |  |  |  |
199 | 2 | 11µs |  |  | return $ok;
200 |  |  |  |  | }
201 |  |  |  |  |
202 |  |  |  |  | sub deep_diag
203 |  |  |  |  | {
204 |  |  |  |  | my $stack = shift;
205 |  |  |  |  | # ick! incArrow and other things expect the stack has to be visible
206 |  |  |  |  | # in a well known place . TODO clean this up
207 |  |  |  |  | local $Stack = $stack;
208 |  |  |  |  |
209 |  |  |  |  | my $where = render_stack('$data', $stack);
210 |  |  |  |  |
211 |  |  |  |  | confess "No stack to diagnose" unless $stack;
212 |  |  |  |  | my $last = $stack->getLast;
213 |  |  |  |  |
214 |  |  |  |  | my $diag;
215 |  |  |  |  | my $message;
216 |  |  |  |  | my $got;
217 |  |  |  |  | my $expected;
218 |  |  |  |  |
219 |  |  |  |  | my $exp = $last->{exp};
220 |  |  |  |  | if (Scalar::Util::blessed($exp))
221 |  |  |  |  | {
222 |  |  |  |  | if ($exp->can("diagnostics"))
223 |  |  |  |  | {
224 |  |  |  |  | $diag = $exp->diagnostics($where, $last);
225 |  |  |  |  | $diag =~ s/\n+$/\n/;
226 |  |  |  |  | }
227 |  |  |  |  | else
228 |  |  |  |  | {
229 |  |  |  |  | if ($exp->can("diag_message"))
230 |  |  |  |  | {
231 |  |  |  |  | $message = $exp->diag_message($where);
232 |  |  |  |  | }
233 |  |  |  |  | }
234 |  |  |  |  | }
235 |  |  |  |  |
236 |  |  |  |  | if (not defined $diag)
237 |  |  |  |  | {
238 |  |  |  |  | $got = $exp->renderGot($last->{got}) unless defined $got;
239 |  |  |  |  | $expected = $exp->renderExp unless defined $expected;
240 |  |  |  |  | $message = "Compared $where" unless defined $message;
241 |  |  |  |  |
242 |  |  |  |  | $diag = <<EOM
243 |  |  |  |  | $message
244 |  |  |  |  | got : $got
245 |  |  |  |  | expect : $expected
246 |  |  |  |  | EOM
247 |  |  |  |  | }
248 |  |  |  |  |
249 |  |  |  |  | return $diag;
250 |  |  |  |  | }
251 |  |  |  |  |
252 |  |  |  |  | sub render_val
253 |  |  |  |  | {
254 |  |  |  |  | my $val = shift;
255 |  |  |  |  |
256 |  |  |  |  | my $rendered;
257 |  |  |  |  | if (defined $val)
258 |  |  |  |  | {
259 |  |  |  |  | $rendered = ref($val) ?
260 |  |  |  |  | (Scalar::Util::refaddr($val) eq $DNE_ADDR ?
261 |  |  |  |  | "Does not exist" :
262 |  |  |  |  | overload::StrVal($val)
263 |  |  |  |  | ) :
264 |  |  |  |  | qq('$val');
265 |  |  |  |  | }
266 |  |  |  |  | else
267 |  |  |  |  | {
268 |  |  |  |  | $rendered = "undef";
269 |  |  |  |  | }
270 |  |  |  |  |
271 |  |  |  |  | return $rendered;
272 |  |  |  |  | }
273 |  |  |  |  |
274 |  |  |  |  | sub descend
275 |  |  |  |  | # spent 17.7ms (644µs+17.1) within Test::Deep::descend which was called 46 times, avg 385µs/call: # 28 times (56µs+-56µs) by Test::Deep::HashElements::descend at line 36 of Test/Deep/HashElements.pm, avg 0s/call # 2 times (95µs+17.6ms) by Test::Deep::cmp_details at line 167, avg 8.86ms/call # 2 times (29µs+-29µs) by Test::Deep::Blessed::descend at line 27 of Test/Deep/Blessed.pm, avg 0s/call # 2 times (48µs+-48µs) by Test::Deep::RefType::descend at line 26 of Test/Deep/RefType.pm, avg 0s/call # 2 times (72µs+-72µs) by Test::Deep::HashKeys::descend at line 27 of Test/Deep/HashKeys.pm, avg 0s/call # 2 times (68µs+-68µs) by Test::Deep::Hash::descend at line 27 of Test/Deep/Hash.pm, avg 0s/call # 2 times (73µs+-73µs) by Test::Deep::Hash::descend at line 31 of Test/Deep/Hash.pm, avg 0s/call # 2 times (85µs+-85µs) by Test::Deep::eq_deeply_cache at line 195, avg 0s/call # 2 times (63µs+-63µs) by Test::Deep::Ref::test_reftype at line 33 of Test/Deep/Ref.pm, avg 0s/call # 2 times (54µs+-54µs) by Test::Deep::Ref::test_class at line 17 of Test/Deep/Ref.pm, avg 0s/call {
276 | 46 | 28µs |  |  | my ($d1, $d2) = @_;
277 |  |  |  |  |
278 | 46 | 88µs |  |  | if (!ref $d1 and !ref $d2)
279 |  |  |  |  | {
280 |  |  |  |  | # Shortcut comparison for the non-reference case.
281 |  |  |  |  | if (defined $d1)
282 |  |  |  |  | {
283 |  |  |  |  | return 1 if defined $d2 and $d1 eq $d2;
284 |  |  |  |  | }
285 |  |  |  |  | else
286 |  |  |  |  | {
287 |  |  |  |  | return 1 if !defined $d2;
288 |  |  |  |  | }
289 |  |  |  |  | }
290 |  |  |  |  |
291 | 18 | 68µs | 18 | 15µs | if (! $Expects and Scalar::Util::blessed($d1) and $d1->isa("Test::Deep::Cmp")) # spent 15µs making 18 calls to Scalar::Util::blessed, avg 844ns/call
292 |  |  |  |  | {
293 |  |  |  |  | my $where = $Stack->render('$data');
294 |  |  |  |  | confess "Found a special comparison in $where\nYou can only use specials in the expects structure";
295 |  |  |  |  | }
296 |  |  |  |  |
297 | 18 | 21µs |  |  | if (ref $d1 and ref $d2)
298 |  |  |  |  | {
299 |  |  |  |  | # this check is only done when we're comparing 2 expecteds against each
300 |  |  |  |  | # other
301 |  |  |  |  |
302 | 14 | 3µs |  |  | if ($Expects and Scalar::Util::blessed($d1) and $d1->isa("Test::Deep::Cmp"))
303 |  |  |  |  | {
304 |  |  |  |  | # check they are the same class
305 |  |  |  |  | return 0 unless Test::Deep::blessed(Scalar::Util::blessed($d2))->descend($d1);
306 |  |  |  |  | if ($d1->can("compare"))
307 |  |  |  |  | {
308 |  |  |  |  | return $d1->compare($d2);
309 |  |  |  |  | }
310 |  |  |  |  | }
311 |  |  |  |  |
312 | 14 | 52µs | 14 | 14µs | my $s1 = Scalar::Util::refaddr($d1); # spent 14µs making 14 calls to Scalar::Util::refaddr, avg 979ns/call
313 | 14 | 39µs | 14 | 9µs | my $s2 = Scalar::Util::refaddr($d2); # spent 9µs making 14 calls to Scalar::Util::refaddr, avg 643ns/call
314 |  |  |  |  |
315 | 14 | 14µs |  |  | if ($s1 eq $s2)
316 |  |  |  |  | {
317 |  |  |  |  | return 1;
318 |  |  |  |  | }
319 | 14 | 34µs | 14 | 1.02ms | if ($CompareCache->cmp($d1, $d2)) # spent 1.02ms making 14 calls to Test::Deep::Cache::cmp, avg 73µs/call
320 |  |  |  |  | {
321 |  |  |  |  | # we've tried comparing these already so either they turned out to
322 |  |  |  |  | # be the same or we must be in a loop and we have to assume they're
323 |  |  |  |  | # the same
324 |  |  |  |  |
325 |  |  |  |  | return 1;
326 |  |  |  |  | }
327 |  |  |  |  | else
328 |  |  |  |  | {
329 | 14 | 26µs | 14 | 545µs | $CompareCache->add($d1, $d2) # spent 545µs making 14 calls to Test::Deep::Cache::add, avg 39µs/call
330 |  |  |  |  | }
331 |  |  |  |  | }
332 |  |  |  |  |
333 | 18 | 32µs | 18 | 1.61ms | $d2 = wrap($d2); # spent 1.61ms making 18 calls to Test::Deep::wrap, avg 90µs/call
334 |  |  |  |  |
335 | 18 | 51µs | 18 | 124µs | $Stack->push({exp => $d2, got => $d1}); # spent 124µs making 18 calls to Test::Deep::Stack::push, avg 7µs/call
336 |  |  |  |  |
337 | 18 | 50µs | 14 | 11µs | if (ref($d1) and (Scalar::Util::refaddr($d1) == $DNE_ADDR)) # spent 11µs making 14 calls to Scalar::Util::refaddr, avg 764ns/call
338 |  |  |  |  | {
339 |  |  |  |  | # whatever it was supposed to be, it didn't exist and so it's an
340 |  |  |  |  | # automatic fail
341 |  |  |  |  | return 0;
342 |  |  |  |  | }
343 |  |  |  |  |
344 | 18 | 35µs | 18 | 37.1ms | if ($d2->descend($d1)) # spent 17.3ms making 2 calls to Test::Deep::Set::descend, avg 8.65ms/call # spent 15.1ms making 2 calls to Test::Deep::Hash::descend, avg 7.56ms/call # spent 3.57ms making 2 calls to Test::Deep::HashKeys::descend, avg 1.79ms/call # spent 662µs making 2 calls to Test::Deep::RefType::descend, avg 331µs/call # spent 241µs making 2 calls to Test::Deep::HashElements::descend, avg 121µs/call # spent 119µs making 2 calls to Test::Deep::Blessed::descend, avg 60µs/call # spent 83µs making 2 calls to Test::Deep::HashKeysOnly::descend, avg 42µs/call # spent 20µs making 4 calls to Test::Deep::Shallow::descend, avg 5µs/call
345 |  |  |  |  | {
346 |  |  |  |  | # print "d1 = $d1, d2 = $d2\nok\n";
347 | 18 | 40µs | 18 | 139µs | $Stack->pop; # spent 139µs making 18 calls to Test::Deep::Stack::pop, avg 8µs/call
348 |  |  |  |  |
349 | 18 | 64µs |  |  | return 1;
350 |  |  |  |  | }
351 |  |  |  |  | else
352 |  |  |  |  | {
353 |  |  |  |  | # print "d1 = $d1, d2 = $d2\nnot ok\n";
354 |  |  |  |  | return 0;
355 |  |  |  |  | }
356 |  |  |  |  | }
357 |  |  |  |  |
358 |  |  |  |  | sub wrap
359 |  |  |  |  | # spent 1.61ms (184µs+1.43) within Test::Deep::wrap which was called 18 times, avg 90µs/call: # 18 times (184µs+1.43ms) by Test::Deep::descend at line 333, avg 90µs/call {
360 | 18 | 6µs |  |  | my $data = shift;
361 |  |  |  |  |
362 | 18 | 187µs | 34 | 40µs | return $data if Scalar::Util::blessed($data) and $data->isa("Test::Deep::Cmp"); # spent 22µs making 16 calls to UNIVERSAL::isa, avg 1µs/call # spent 18µs making 18 calls to Scalar::Util::blessed, avg 972ns/call
363 |  |  |  |  |
364 | 2 | 6µs | 2 | 36µs | my ($class, $base) = class_base($data); # spent 36µs making 2 calls to Test::Deep::class_base, avg 18µs/call
365 |  |  |  |  |
366 | 2 | 600ns |  |  | my $cmp;
367 |  |  |  |  |
368 | 2 | 2µs |  |  | if($base eq '')
369 |  |  |  |  | {
370 |  |  |  |  | $cmp = shallow($data);
371 |  |  |  |  | }
372 |  |  |  |  | else
373 |  |  |  |  | {
374 | 2 | 10µs | 2 | 2µs | my $addr = Scalar::Util::refaddr($data); # spent 2µs making 2 calls to Scalar::Util::refaddr, avg 1µs/call
375 |  |  |  |  |
376 | 2 | 2µs |  |  | return $WrapCache{$addr} if $WrapCache{$addr};
377 |  |  |  |  |
378 | 2 | 8µs | 2 | 1.35ms | if($base eq 'ARRAY') # spent 1.35ms making 2 calls to Test::Deep::__ANON__[Test/Deep.pm:81], avg 677µs/call
379 |  |  |  |  | {
380 |  |  |  |  | $cmp = array($data);
381 |  |  |  |  | }
382 |  |  |  |  | elsif($base eq 'HASH')
383 |  |  |  |  | {
384 |  |  |  |  | $cmp = hash($data);
385 |  |  |  |  | }
386 |  |  |  |  | elsif($base eq 'SCALAR' or $base eq 'REF')
387 |  |  |  |  | {
388 |  |  |  |  | $cmp = scalref($data);
389 |  |  |  |  | }
390 |  |  |  |  | elsif(($base eq 'Regexp') or ($base eq 'REGEXP'))
391 |  |  |  |  | {
392 |  |  |  |  | $cmp = regexpref($data);
393 |  |  |  |  | }
394 |  |  |  |  | else
395 |  |  |  |  | {
396 |  |  |  |  | $cmp = shallow($data);
397 |  |  |  |  | }
398 |  |  |  |  |
399 | 2 | 4µs |  |  | $WrapCache{$addr} = $cmp;
400 |  |  |  |  | }
401 | 2 | 6µs |  |  | return $cmp;
402 |  |  |  |  | }
403 |  |  |  |  |
404 |  |  |  |  | sub class_base
405 |  |  |  |  | # spent 36µs (32+3) within Test::Deep::class_base which was called 2 times, avg 18µs/call: # 2 times (32µs+3µs) by Test::Deep::wrap at line 364, avg 18µs/call {
406 | 2 | 1µs |  |  | my $val = shift;
407 |  |  |  |  |
408 | 2 | 2µs |  |  | if (ref $val)
409 |  |  |  |  | {
410 | 2 | 14µs | 2 | 1µs | my $blessed = Scalar::Util::blessed($val); # spent 1µs making 2 calls to Scalar::Util::blessed, avg 600ns/call
411 | 2 | 2µs |  |  | $blessed = defined($blessed) ? $blessed : "";
412 | 2 | 10µs | 2 | 2µs | my $reftype = Scalar::Util::reftype($val); # spent 2µs making 2 calls to Scalar::Util::reftype, avg 1µs/call
413 |  |  |  |  |
414 |  |  |  |  |
415 | 2 | 1µs |  |  | if ($Test::Deep::RegexpVersion::OldStyle) {
416 |  |  |  |  | if ($blessed eq "Regexp" and $reftype eq "SCALAR")
417 |  |  |  |  | {
418 |  |  |  |  | $reftype = "Regexp"
419 |  |  |  |  | }
420 |  |  |  |  | }
421 | 2 | 9µs |  |  | return ($blessed, $reftype);
422 |  |  |  |  | }
423 |  |  |  |  | else
424 |  |  |  |  | {
425 |  |  |  |  | return ("", "");
426 |  |  |  |  | }
427 |  |  |  |  | }
428 |  |  |  |  |
429 |  |  |  |  | sub render_stack
430 |  |  |  |  | {
431 |  |  |  |  | my ($var, $stack) = @_;
432 |  |  |  |  |
433 |  |  |  |  | return $stack->render($var);
434 |  |  |  |  | }
435 |  |  |  |  |
436 |  |  |  |  | sub cmp_methods
437 |  |  |  |  | {
438 |  |  |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
439 |  |  |  |  | return cmp_deeply(shift, methods(@{shift()}), shift);
440 |  |  |  |  | }
441 |  |  |  |  |
442 |  |  |  |  | sub requireclass
443 |  |  |  |  | {
444 |  |  |  |  | require Test::Deep::Class;
445 |  |  |  |  |
446 |  |  |  |  | my $val = shift;
447 |  |  |  |  |
448 |  |  |  |  | return Test::Deep::Class->new(1, $val);
449 |  |  |  |  | }
450 |  |  |  |  |
451 |  |  |  |  | # docs and export say this is called useclass, doh!
452 |  |  |  |  |
453 | 1 | 1µs |  |  | *useclass = \&requireclass;
454 |  |  |  |  |
455 |  |  |  |  | sub noclass
456 |  |  |  |  | {
457 |  |  |  |  | require Test::Deep::Class;
458 |  |  |  |  |
459 |  |  |  |  | my $val = shift;
460 |  |  |  |  |
461 |  |  |  |  | return Test::Deep::Class->new(0, $val);
462 |  |  |  |  | }
463 |  |  |  |  |
464 |  |  |  |  | sub set
465 |  |  |  |  | {
466 |  |  |  |  | require Test::Deep::Set;
467 |  |  |  |  |
468 |  |  |  |  | return Test::Deep::Set->new(1, "", @_);
469 |  |  |  |  | }
470 |  |  |  |  |
471 |  |  |  |  | sub supersetof
472 |  |  |  |  | {
473 |  |  |  |  | require Test::Deep::Set;
474 |  |  |  |  |
475 |  |  |  |  | return Test::Deep::Set->new(1, "sup", @_);
476 |  |  |  |  | }
477 |  |  |  |  |
478 |  |  |  |  | sub subsetof
479 |  |  |  |  | {
480 |  |  |  |  | require Test::Deep::Set;
481 |  |  |  |  |
482 |  |  |  |  | return Test::Deep::Set->new(1, "sub", @_);
483 |  |  |  |  | }
484 |  |  |  |  |
485 |  |  |  |  | sub cmp_set
486 |  |  |  |  | {
487 |  |  |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
488 |  |  |  |  | return cmp_deeply(shift, set(@{shift()}), shift);
489 |  |  |  |  | }
490 |  |  |  |  |
491 |  |  |  |  | sub bag
492 |  |  |  |  | # spent 1.95ms (856µs+1.10) within Test::Deep::bag which was called 2 times, avg 977µs/call: # 2 times (856µs+1.10ms) by Test::Deep::cmp_bag at line 518, avg 977µs/call {
493 | 2 | 77µs |  |  | require Test::Deep::Set;
494 |  |  |  |  |
495 | 2 | 25µs | 2 | 212µs | return Test::Deep::Set->new(0, "", @_); # spent 212µs making 2 calls to Test::Deep::Cmp::new, avg 106µs/call
496 |  |  |  |  | }
497 |  |  |  |  |
498 |  |  |  |  | sub superbagof
499 |  |  |  |  | {
500 |  |  |  |  | require Test::Deep::Set;
501 |  |  |  |  |
502 |  |  |  |  | return Test::Deep::Set->new(0, "sup", @_);
503 |  |  |  |  | }
504 |  |  |  |  |
505 |  |  |  |  | sub subbagof
506 |  |  |  |  | {
507 |  |  |  |  | require Test::Deep::Set;
508 |  |  |  |  |
509 |  |  |  |  | return Test::Deep::Set->new(0, "sub", @_);
510 |  |  |  |  | }
511 |  |  |  |  |
512 |  |  |  |  | sub cmp_bag
513 |  |  |  |  | # spent 20.9ms (29µs+20.8) within Test::Deep::cmp_bag which was called 2 times, avg 10.4ms/call: # once (15µs+17.6ms) by main::RUNTIME at line 40 of t/optimization.t # once (14µs+3.23ms) by main::RUNTIME at line 74 of t/optimization.t {
514 | 2 | 2µs |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
515 | 2 | 3µs |  |  | my $ref = ref($_[1]) || "";
516 | 2 | 2µs |  |  | confess "Argument 2 to cmp_bag is not an ARRAY ref (".render_val($_[1]).")"
517 |  |  |  |  | unless $ref eq "ARRAY";
518 | 2 | 21µs | 4 | 20.8ms | return cmp_deeply(shift, bag(@{shift()}), shift); # spent 18.9ms making 2 calls to Test::Deep::cmp_deeply, avg 9.45ms/call # spent 1.95ms making 2 calls to Test::Deep::bag, avg 977µs/call
519 |  |  |  |  | }
520 |  |  |  |  |
521 |  |  |  |  | sub superhashof
522 |  |  |  |  | {
523 |  |  |  |  | require Test::Deep::Hash;
524 |  |  |  |  |
525 |  |  |  |  | my $val = shift;
526 |  |  |  |  |
527 |  |  |  |  | return Test::Deep::SuperHash->new($val);
528 |  |  |  |  | }
529 |  |  |  |  |
530 |  |  |  |  | sub subhashof
531 |  |  |  |  | {
532 |  |  |  |  | require Test::Deep::Hash;
533 |  |  |  |  |
534 |  |  |  |  | my $val = shift;
535 |  |  |  |  |
536 |  |  |  |  | return Test::Deep::SubHash->new($val);
537 |  |  |  |  | }
538 |  |  |  |  |
539 |  |  |  |  | sub builder
540 |  |  |  |  | {
541 |  |  |  |  | if (@_)
542 |  |  |  |  | {
543 |  |  |  |  | $Test = shift;
544 |  |  |  |  | }
545 |  |  |  |  | return $Test;
546 |  |  |  |  | }
547 |  |  |  |  |
548 | 1 | 35µs |  |  | 1;
549 |  |  |  |  |
550 |  |  |  |  | __END__
|  |  |  |  | # spent 59µs within Test::Deep::CORE:subst which was called 30 times, avg 2µs/call: # 30 times (59µs+0s) by main::BEGIN@7 at line 77, avg 2µs/call sub Test::Deep::CORE:subst; # opcode