Profile of lib/PONAPI/Builder/Document.pm

← Index
NYTProf Performance Profile «line view»
For script/ponapi
Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:11 2016

Filename | /home/mickey/git_tree/PONAPI/Server/lib/PONAPI/Builder/Document.pm
Statements | Executed 4058633 statements in 13.7s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
100001 | 1 | 1 | 8.03s | 58.8s | PONAPI::Builder::Document::::buildPONAPI::Builder::Document::build
183655 | 1 | 1 | 4.56s | 40.6s | PONAPI::Builder::Document::::add_resourcePONAPI::Builder::Document::add_resource
233411 | 2 | 1 | 2.35s | 3.45s | PONAPI::Builder::Document::::has_resourcePONAPI::Builder::Document::has_resource
100001 | 1 | 1 | 1.40s | 3.27s | PONAPI::Builder::Document::::add_self_linkPONAPI::Builder::Document::add_self_link
86592 | 1 | 1 | 1.28s | 15.1s | PONAPI::Builder::Document::::add_includedPONAPI::Builder::Document::add_included
50245 | 1 | 1 | 424ms | 693ms | PONAPI::Builder::Document::::convert_to_collectionPONAPI::Builder::Document::convert_to_collection
100001 | 1 | 1 | 264ms | 264ms | PONAPI::Builder::Document::::__ANON__[lib/PONAPI/Builder/Document.pm:70]PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:70]
100001 | 2 | 1 | 214ms | 214ms | PONAPI::Builder::Document::::__ANON__[lib/PONAPI/Builder/Document.pm:56]PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:56]
100001 | 1 | 1 | 205ms | 205ms | PONAPI::Builder::Document::::__ANON__[lib/PONAPI/Builder/Document.pm:25]PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:25]
1 | 1 | 1 | 758µs | 435ms | PONAPI::Builder::Document::::BEGIN@6PONAPI::Builder::Document::BEGIN@6
1 | 1 | 1 | 310µs | 25.0ms | PONAPI::Builder::Document::::BEGIN@8PONAPI::Builder::Document::BEGIN@8
1 | 1 | 1 | 200µs | 8.97ms | PONAPI::Builder::Document::::BEGIN@7PONAPI::Builder::Document::BEGIN@7
1 | 1 | 1 | 17µs | 2.94ms | PONAPI::Builder::Document::::BEGIN@4PONAPI::Builder::Document::BEGIN@4
1 | 1 | 1 | 10µs | 88µs | PONAPI::Builder::Document::::BEGIN@205PONAPI::Builder::Document::BEGIN@205
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::__ANON__[lib/PONAPI/Builder/Document.pm:34]PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:34]
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::__ANON__[lib/PONAPI/Builder/Document.pm:40]PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:40]
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::_build_errors_builderPONAPI::Builder::Document::_build_errors_builder
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::add_null_resourcePONAPI::Builder::Document::add_null_resource
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::has_errorsPONAPI::Builder::Document::has_errors
0 | 0 | 0 | 0s | 0s | PONAPI::Builder::Document::::has_resourcesPONAPI::Builder::Document::has_resources

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | # ABSTRACT: document builder class
2 |  |  |  |  | package PONAPI::Builder::Document;
3 |  |  |  |  |
4 | 2 | 40µs | 2 | 5.86ms | # spent 2.94ms (17µs+2.92) within PONAPI::Builder::Document::BEGIN@4 which was called: # once (17µs+2.92ms) by PONAPI::DAO::Request::BEGIN@7 at line 4 use Moose; # spent 2.94ms making 1 call to PONAPI::Builder::Document::BEGIN@4 # spent 2.92ms making 1 call to Moose::import
5 |  |  |  |  |
6 | 2 | 111µs | 1 | 435ms | # spent 435ms (758µs+434) within PONAPI::Builder::Document::BEGIN@6 which was called: # once (758µs+434ms) by PONAPI::DAO::Request::BEGIN@7 at line 6 use PONAPI::Builder::Resource; # spent 435ms making 1 call to PONAPI::Builder::Document::BEGIN@6
7 | 2 | 117µs | 1 | 8.97ms | # spent 8.97ms (200µs+8.77) within PONAPI::Builder::Document::BEGIN@7 which was called: # once (200µs+8.77ms) by PONAPI::DAO::Request::BEGIN@7 at line 7 use PONAPI::Builder::Resource::Null; # spent 8.97ms making 1 call to PONAPI::Builder::Document::BEGIN@7
8 | 2 | 740µs | 1 | 25.0ms | # spent 25.0ms (310µs+24.7) within PONAPI::Builder::Document::BEGIN@8 which was called: # once (310µs+24.7ms) by PONAPI::DAO::Request::BEGIN@7 at line 8 use PONAPI::Builder::Errors; # spent 25.0ms making 1 call to PONAPI::Builder::Document::BEGIN@8
9 |  |  |  |  |
10 | 1 | 3µs | 1 | 24.7ms | with 'PONAPI::Builder', # spent 24.7ms making 1 call to Moose::with
11 |  |  |  |  | 'PONAPI::Builder::Role::HasLinksBuilder',
12 |  |  |  |  | 'PONAPI::Builder::Role::HasMeta',
13 |  |  |  |  | 'PONAPI::Builder::Role::HasPagination';
14 |  |  |  |  |
15 | 1 | 4µs | 1 | 1.70ms | has version => ( # spent 1.70ms making 1 call to Moose::has
16 |  |  |  |  | is => 'ro',
17 |  |  |  |  | isa => 'Str',
18 |  |  |  |  | required => 1,
19 |  |  |  |  | );
20 |  |  |  |  |
21 |  |  |  |  | has status => (
22 |  |  |  |  | init_arg => undef,
23 |  |  |  |  | is => 'ro',
24 |  |  |  |  | isa => 'Num',
25 | 100001 | 559ms |  |  | # spent 205ms within PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:25] which was called 100001 times, avg 2µs/call: # 100001 times (205ms+0s) by PONAPI::Builder::Document::status at line 12 of (eval 45)[Eval/Closure.pm:144], avg 2µs/call default => sub { 200 },
26 | 1 | 4µs | 1 | 3.33ms | writer => 'set_status', # spent 3.33ms making 1 call to Moose::has
27 |  |  |  |  | lazy => 1,
28 |  |  |  |  | predicate => 'has_status',
29 |  |  |  |  | );
30 |  |  |  |  |
31 |  |  |  |  | has req_base => (
32 |  |  |  |  | is => 'ro',
33 |  |  |  |  | isa => 'Str',
34 |  |  |  |  | default => sub { '/' },
35 | 1 | 5µs | 1 | 1.30ms | ); # spent 1.30ms making 1 call to Moose::has
36 |  |  |  |  |
37 |  |  |  |  | has req_path => (
38 |  |  |  |  | is => 'ro',
39 |  |  |  |  | isa => 'Str',
40 |  |  |  |  | default => sub { '/' },
41 | 1 | 4µs | 1 | 1.25ms | ); # spent 1.25ms making 1 call to Moose::has
42 |  |  |  |  |
43 | 1 | 1µs | 1 | 2.23ms | has is_collection => ( # spent 2.23ms making 1 call to Moose::has
44 |  |  |  |  | is => 'ro',
45 |  |  |  |  | writer => '_set_is_collection',
46 |  |  |  |  | isa => 'Bool',
47 |  |  |  |  | default => 0
48 |  |  |  |  | );
49 |  |  |  |  |
50 |  |  |  |  | has _included => (
51 |  |  |  |  | init_arg => undef,
52 |  |  |  |  | traits => [ 'Array' ],
53 |  |  |  |  | is => 'ro',
54 |  |  |  |  | isa => 'ArrayRef[ PONAPI::Builder::Resource ]',
55 |  |  |  |  | lazy => 1,
56 | 100001 | 535ms |  |  | # spent 214ms within PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:56] which was called 100001 times, avg 2µs/call: # 55431 times (118ms+0s) by PONAPI::Builder::Document::has_included at line 14 of (eval 45)[Eval/Closure.pm:144], avg 2µs/call # 44570 times (96.6ms+0s) by PONAPI::Builder::Document::_add_included at line 13 of (eval 45)[Eval/Closure.pm:144], avg 2µs/call default => sub { +[] },
57 | 1 | 7µs | 1 | 6.48ms | handles => { # spent 6.48ms making 1 call to Moose::has
58 |  |  |  |  | 'has_included' => 'count',
59 |  |  |  |  | # private ...
60 |  |  |  |  | '_add_included' => 'push',
61 |  |  |  |  | }
62 |  |  |  |  | );
63 |  |  |  |  |
64 |  |  |  |  | has _resource_builders => (
65 |  |  |  |  | init_arg => undef,
66 |  |  |  |  | traits => [ 'Array' ],
67 |  |  |  |  | is => 'ro',
68 |  |  |  |  | isa => 'ArrayRef[ PONAPI::Builder::Resource | PONAPI::Builder::Resource::Null ]',
69 |  |  |  |  | lazy => 1,
70 | 100001 | 628ms |  |  | # spent 264ms within PONAPI::Builder::Document::__ANON__[lib/PONAPI/Builder/Document.pm:70] which was called 100001 times, avg 3µs/call: # 100001 times (264ms+0s) by PONAPI::Builder::Document::_add_resource_builder at line 13 of (eval 45)[Eval/Closure.pm:144], avg 3µs/call default => sub { +[] },
71 | 1 | 9µs | 1 | 15.7ms | predicate => 'has_resource_builders', # spent 15.7ms making 1 call to Moose::has
72 |  |  |  |  | handles => {
73 |  |  |  |  | '_num_resource_builders' => 'count',
74 |  |  |  |  | # private ...
75 |  |  |  |  | '_add_resource_builder' => 'push',
76 |  |  |  |  | '_get_resource_builder' => 'get',
77 |  |  |  |  | }
78 |  |  |  |  | );
79 |  |  |  |  |
80 | 1 | 2µs | 1 | 2.55ms | has errors_builder => ( # spent 2.55ms making 1 call to Moose::has
81 |  |  |  |  | init_arg => undef,
82 |  |  |  |  | is => 'ro',
83 |  |  |  |  | isa => 'PONAPI::Builder::Errors',
84 |  |  |  |  | lazy => 1,
85 |  |  |  |  | predicate => 'has_errors_builder',
86 |  |  |  |  | builder => '_build_errors_builder',
87 |  |  |  |  | );
88 |  |  |  |  |
89 |  |  |  |  | sub _build_errors_builder { PONAPI::Builder::Errors->new( parent => $_[0] ) }
90 |  |  |  |  |
91 | 50245 | 381ms | 50245 | 270ms | # spent 693ms (424+270) within PONAPI::Builder::Document::convert_to_collection which was called 50245 times, avg 14µs/call: # 50245 times (424ms+270ms) by PONAPI::DAO::Request::RetrieveAll::execute at line 19 of lib/PONAPI/DAO/Request/RetrieveAll.pm, avg 14µs/call sub convert_to_collection { $_[0]->_set_is_collection(1) } # spent 270ms making 50245 calls to PONAPI::Builder::Document::_set_is_collection, avg 5µs/call
92 |  |  |  |  |
93 |  |  |  |  | sub has_errors {
94 |  |  |  |  | my $self = shift;
95 |  |  |  |  | return $self->errors_builder->has_errors
96 |  |  |  |  | if $self->has_errors_builder and $self->errors_builder->has_errors;
97 |  |  |  |  | return 0;
98 |  |  |  |  | }
99 |  |  |  |  |
100 |  |  |  |  | # spent 3.45s (2.35+1.11) within PONAPI::Builder::Document::has_resource which was called 233411 times, avg 15µs/call: # 183655 times (1.82s+862ms) by PONAPI::Builder::Document::add_resource at line 113, avg 15µs/call # 49756 times (524ms+243ms) by PONAPI::Builder::Document::build at line 160, avg 15µs/call sub has_resource {
101 | 233411 | 101ms |  |  | my $self = shift;
102 | 233411 | 1.70s | 366821 | 1.11s | $self->has_resource_builders && $self->_num_resource_builders > 0; # spent 557ms making 233411 calls to PONAPI::Builder::Document::has_resource_builders, avg 2µs/call # spent 548ms making 133410 calls to PONAPI::Builder::Document::_num_resource_builders, avg 4µs/call
103 |  |  |  |  | }
104 |  |  |  |  |
105 |  |  |  |  | sub has_resources {
106 |  |  |  |  | my $self = shift;
107 |  |  |  |  | $self->has_resource_builders && $self->_num_resource_builders > 1;
108 |  |  |  |  | }
109 |  |  |  |  |
110 |  |  |  |  | # spent 40.6s (4.56+36.0) within PONAPI::Builder::Document::add_resource which was called 183655 times, avg 221µs/call: # 183655 times (4.56s+36.0s) by Test::PONAPI::Repository::MockDB::_add_resources at line 563 of lib/Test/PONAPI/Repository/MockDB.pm, avg 221µs/call sub add_resource {
111 | 183655 | 319ms |  |  | my ($self, %args) = @_;
112 |  |  |  |  |
113 | 183655 | 589ms | 267309 | 2.91s | die 'Cannot add more then one resource unless the Document is in collection mode' # spent 2.69s making 183655 calls to PONAPI::Builder::Document::has_resource, avg 15µs/call # spent 224ms making 83654 calls to PONAPI::Builder::Document::is_collection, avg 3µs/call
114 |  |  |  |  | if $self->has_resource && !$self->is_collection;
115 |  |  |  |  |
116 | 183655 | 1.08s | 183655 | 27.4s | my $builder = PONAPI::Builder::Resource->new( %args, parent => $self ); # spent 27.4s making 183655 calls to PONAPI::Builder::Resource::new, avg 149µs/call
117 | 183655 | 429ms | 183655 | 5.77s | $self->_add_resource_builder( $builder ); # spent 5.77s making 183655 calls to PONAPI::Builder::Document::_add_resource_builder, avg 31µs/call
118 | 183655 | 969ms |  |  | return $builder;
119 |  |  |  |  | }
120 |  |  |  |  |
121 |  |  |  |  | sub add_null_resource {
122 |  |  |  |  | my $self = shift;
123 |  |  |  |  |
124 |  |  |  |  | my $builder = PONAPI::Builder::Resource::Null->new( parent => $self );
125 |  |  |  |  | $self->_add_resource_builder( $builder );
126 |  |  |  |  | return $builder;
127 |  |  |  |  | }
128 |  |  |  |  |
129 |  |  |  |  | # spent 15.1s (1.28+13.9) within PONAPI::Builder::Document::add_included which was called 86592 times, avg 175µs/call: # 86592 times (1.28s+13.9s) by Test::PONAPI::Repository::MockDB::_add_included at line 686 of lib/Test/PONAPI/Repository/MockDB.pm, avg 175µs/call sub add_included {
130 | 86592 | 140ms |  |  | my ($self, %args) = @_;
131 | 86592 | 313ms | 86592 | 11.6s | my $builder = PONAPI::Builder::Resource->new( parent => $self, %args ); # spent 11.6s making 86592 calls to PONAPI::Builder::Resource::new, avg 134µs/call
132 | 86592 | 191ms | 86592 | 2.22s | $self->_add_included( $builder ); # spent 2.22s making 86592 calls to PONAPI::Builder::Document::_add_included, avg 26µs/call
133 | 86592 | 408ms |  |  | return $builder;
134 |  |  |  |  | }
135 |  |  |  |  |
136 |  |  |  |  | # spent 3.27s (1.40+1.87) within PONAPI::Builder::Document::add_self_link which was called 100001 times, avg 33µs/call: # 100001 times (1.40s+1.87s) by PONAPI::DAO::Request::response at line 140 of lib/PONAPI/DAO/Request.pm, avg 33µs/call sub add_self_link {
137 | 100001 | 44.6ms |  |  | my $self = shift;
138 | 100001 | 463ms | 300003 | 1.87s | $self->links_builder->add_link( self => $self->req_path ); # spent 1.40s making 100001 calls to PONAPI::Builder::Links::add_link, avg 14µs/call # spent 297ms making 100001 calls to PONAPI::Builder::Document::req_path, avg 3µs/call # spent 167ms making 100001 calls to PONAPI::Builder::Document::links_builder, avg 2µs/call
139 | 100001 | 423ms |  |  | return $self;
140 |  |  |  |  | }
141 |  |  |  |  |
142 |  |  |  |  | # spent 58.8s (8.03+50.8) within PONAPI::Builder::Document::build which was called 100001 times, avg 588µs/call: # 100001 times (8.03s+50.8s) by PONAPI::DAO::Request::response at line 144 of lib/PONAPI/DAO/Request.pm, avg 588µs/call sub build {
143 | 100001 | 51.0ms |  |  | my $self = shift;
144 | 100001 | 71.4ms |  |  | my %args = @_;
145 | 100001 | 420ms | 100001 | 264ms | my $result = +{ jsonapi => { version => $self->version } }; # spent 264ms making 100001 calls to PONAPI::Builder::Document::version, avg 3µs/call
146 |  |  |  |  |
147 | 100001 | 272ms | 100001 | 238ms | if ( ! $self->has_errors_builder ) { # spent 238ms making 100001 calls to PONAPI::Builder::Document::has_errors_builder, avg 2µs/call
148 | 100001 | 231ms | 100001 | 372ms | $result->{meta} = $self->_meta if $self->has_meta; # spent 372ms making 100001 calls to PONAPI::Builder::Document::has_meta, avg 4µs/call
149 | 100001 | 555ms | 300003 | 2.95s | $result->{links} = $self->links_builder->build if $self->has_links_builder; # spent 2.58s making 100001 calls to PONAPI::Builder::Links::build, avg 26µs/call # spent 229ms making 100001 calls to PONAPI::Builder::Document::has_links_builder, avg 2µs/call # spent 146ms making 100001 calls to PONAPI::Builder::Document::links_builder, avg 1µs/call
150 |  |  |  |  |
151 | 100001 | 221ms | 100001 | 169ms | if ( $self->has_resource_builders ) { # spent 169ms making 100001 calls to PONAPI::Builder::Document::has_resource_builders, avg 2µs/call
152 | 100001 | 261ms | 100001 | 254ms | if ( $self->is_collection ) { # spent 254ms making 100001 calls to PONAPI::Builder::Document::is_collection, avg 3µs/call
153 |  |  |  |  | # if it is a collection, then
154 |  |  |  |  | # call build on each one ...
155 | 184144 | 449ms | 184144 | 25.2s | $result->{data} = [ map { $_->build( %args ) } @{ $self->_resource_builders } ]; # spent 25.0s making 133899 calls to PONAPI::Builder::Resource::build, avg 187µs/call # spent 182ms making 50245 calls to PONAPI::Builder::Document::_resource_builders, avg 4µs/call
156 |  |  |  |  | }
157 |  |  |  |  | else {
158 |  |  |  |  | # if it is a single resource,
159 |  |  |  |  | # just use that one
160 | 49756 | 340ms | 149268 | 12.0s | $result->{data} = $self->_get_resource_builder(0)->build( %args ) # spent 10.7s making 49756 calls to PONAPI::Builder::Resource::build, avg 215µs/call # spent 767ms making 49756 calls to PONAPI::Builder::Document::has_resource, avg 15µs/call # spent 562ms making 49756 calls to PONAPI::Builder::Document::_get_resource_builder, avg 11µs/call
161 |  |  |  |  | if $self->has_resource;
162 |  |  |  |  | }
163 |  |  |  |  |
164 |  |  |  |  |
165 |  |  |  |  | # http://jsonapi.org/format/#document-compound-documents
166 |  |  |  |  | # "A compound document MUST NOT include more than one resource
167 |  |  |  |  | # object for each type and id pair."
168 |  |  |  |  | # So in short, we need to check that we don't have any duplicates.
169 | 100001 | 307ms | 100001 | 1.72s | if ( $self->has_included ) { # spent 1.72s making 100001 calls to PONAPI::Builder::Document::has_included, avg 17µs/call
170 | 44570 | 106ms | 44570 | 162ms | my $included_builders = $self->_included; # spent 162ms making 44570 calls to PONAPI::Builder::Document::_included, avg 4µs/call
171 | 44570 | 15.2ms |  |  | my (@included, %seen);
172 | 44570 | 55.5ms |  |  | foreach my $builder ( @$included_builders ) {
173 | 86592 | 186ms |  |  | next if $seen{$builder->{type}}{$builder->{id}}++;
174 | 78113 | 165ms | 78113 | 7.32s | push @included, $builder->build( %args ); # spent 7.32s making 78113 calls to PONAPI::Builder::Resource::build, avg 94µs/call
175 |  |  |  |  | }
176 | 44570 | 95.8ms |  |  | $result->{included} = \@included;
177 |  |  |  |  | }
178 |  |  |  |  | }
179 |  |  |  |  | else {
180 |  |  |  |  | if ( $self->is_collection ) {
181 |  |  |  |  | $result->{data} = [];
182 |  |  |  |  | }
183 |  |  |  |  | else {
184 |  |  |  |  | die "[PANIC] OH NOES, THIS SHOULD NEVER HAPPEN!!!!!"
185 |  |  |  |  | if ! $self->has_meta;
186 |  |  |  |  | }
187 |  |  |  |  | }
188 |  |  |  |  | }
189 |  |  |  |  |
190 | 100001 | 200ms | 100001 | 171ms | if ( $self->has_errors_builder ) { # spent 171ms making 100001 calls to PONAPI::Builder::Document::has_errors_builder, avg 2µs/call
191 |  |  |  |  | my $errors = $self->errors_builder->build;
192 |  |  |  |  | if ( $errors ) {
193 |  |  |  |  | $_->{status} //= $self->status for @$errors;
194 |  |  |  |  | }
195 |  |  |  |  | return +{
196 |  |  |  |  | jsonapi => +{ version => $self->version },
197 |  |  |  |  | errors => $errors,
198 |  |  |  |  | };
199 |  |  |  |  | }
200 |  |  |  |  |
201 | 100001 | 469ms |  |  | return $result;
202 |  |  |  |  | }
203 |  |  |  |  |
204 | 1 | 4µs | 2 | 4.79ms | __PACKAGE__->meta->make_immutable; # spent 4.77ms making 1 call to Class::MOP::Class::make_immutable # spent 12µs making 1 call to PONAPI::Builder::Document::meta
205 | 3 | 93µs | 2 | 167µs | # spent 88µs (10+78) within PONAPI::Builder::Document::BEGIN@205 which was called: # once (10µs+78µs) by PONAPI::DAO::Request::BEGIN@7 at line 205 no Moose; 1; # spent 88µs making 1 call to PONAPI::Builder::Document::BEGIN@205 # spent 78µs making 1 call to Moose::unimport
206 |  |  |  |  |
207 |  |  |  |  | __END__