Profile of lib/Test/PONAPI/Repository/MockDB/Table.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/Test/PONAPI/Repository/MockDB/Table.pm
Statements | Executed 7923372 statements in 20.1s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
368116 | 3 | 1 | 12.4s | 24.5s | Test::PONAPI::Repository::MockDB::Table::::select_stmtTest::PONAPI::Repository::MockDB::Table::select_stmt
368116 | 1 | 1 | 5.79s | 7.22s | Test::PONAPI::Repository::MockDB::Table::::_stmt_filtersTest::PONAPI::Repository::MockDB::Table::_stmt_filters
368116 | 1 | 1 | 4.21s | 4.78s | Test::PONAPI::Repository::MockDB::Table::::_stmt_columnsTest::PONAPI::Repository::MockDB::Table::_stmt_columns
1 | 1 | 1 | 18µs | 3.06ms | Test::PONAPI::Repository::MockDB::Table::::BEGIN@4Test::PONAPI::Repository::MockDB::Table::BEGIN@4
1 | 1 | 1 | 9µs | 9µs | Test::PONAPI::Repository::MockDB::Table::::BEGIN@6Test::PONAPI::Repository::MockDB::Table::BEGIN@6
1 | 1 | 1 | 8µs | 80µs | Test::PONAPI::Repository::MockDB::Table::::BEGIN@167Test::PONAPI::Repository::MockDB::Table::BEGIN@167
4 | 1 | 1 | 4µs | 4µs | Test::PONAPI::Repository::MockDB::Table::::__ANON__[lib/Test/PONAPI/Repository/MockDB/Table.pm:23]Test::PONAPI::Repository::MockDB::Table::__ANON__[lib/Test/PONAPI/Repository/MockDB/Table.pm:23]
0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::::delete_stmtTest::PONAPI::Repository::MockDB::Table::delete_stmt
0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::::insert_stmtTest::PONAPI::Repository::MockDB::Table::insert_stmt
0 | 0 | 0 | 0s | 0s | Test::PONAPI::Repository::MockDB::Table::::update_stmtTest::PONAPI::Repository::MockDB::Table::update_stmt

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | # ABSTRACT: mock repository - table class
2 |  |  |  |  | package Test::PONAPI::Repository::MockDB::Table;
3 |  |  |  |  |
4 | 2 | 52µs | 2 | 6.10ms | # spent 3.06ms (18µs+3.04) within Test::PONAPI::Repository::MockDB::Table::BEGIN@4 which was called: # once (18µs+3.04ms) by Module::Runtime::require_module at line 4 use Moose; # spent 3.06ms making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@4 # spent 3.04ms making 1 call to Moose::import
5 |  |  |  |  |
6 | 2 | 706µs | 1 | 9µs | # spent 9µs within Test::PONAPI::Repository::MockDB::Table::BEGIN@6 which was called: # once (9µs+0s) by Module::Runtime::require_module at line 6 use Test::PONAPI::Repository::MockDB::Table::Relationships; # spent 9µs making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@6
7 |  |  |  |  |
8 | 1 | 3µs | 1 | 9.40ms | has [qw/TYPE TABLE ID_COLUMN/] => ( # spent 9.40ms making 1 call to Moose::has
9 |  |  |  |  | is => 'ro',
10 |  |  |  |  | isa => 'Str',
11 |  |  |  |  | required => 1,
12 |  |  |  |  | );
13 |  |  |  |  |
14 | 1 | 2µs | 1 | 1.24ms | has COLUMNS => ( # spent 1.24ms making 1 call to Moose::has
15 |  |  |  |  | is => 'ro',
16 |  |  |  |  | isa => 'ArrayRef',
17 |  |  |  |  | required => 1,
18 |  |  |  |  | );
19 |  |  |  |  |
20 |  |  |  |  | has RELATIONS => (
21 |  |  |  |  | is => 'ro',
22 |  |  |  |  | isa => 'HashRef[Test::PONAPI::Repository::MockDB::Table::Relationships]',
23 | 4 | 14µs |  |  | # spent 4µs within Test::PONAPI::Repository::MockDB::Table::__ANON__[lib/Test/PONAPI/Repository/MockDB/Table.pm:23] which was called 4 times, avg 1µs/call: # 4 times (4µs+0s) by Test::PONAPI::Repository::MockDB::Table::Relationships::new at line 75 of (eval 45)[Eval/Closure.pm:144], avg 1µs/call default => sub { {} },
24 | 1 | 4µs | 1 | 2.44ms | ); # spent 2.44ms making 1 call to Moose::has
25 |  |  |  |  |
26 |  |  |  |  | sub insert_stmt {
27 |  |  |  |  | my ($self, %args) = @_;
28 |  |  |  |  |
29 |  |  |  |  | my $table = $args{table};
30 |  |  |  |  | my $values = $args{values};
31 |  |  |  |  |
32 |  |  |  |  | # NOTE: this is a bunch of bad practices rolled together.
33 |  |  |  |  | # We're crafting our own SQL and not escaping the table/columns,
34 |  |  |  |  | # as well as using sqlite-specific features.
35 |  |  |  |  | # Ordinarily, you'd use DBIx::Class or at least SQL::Composer
36 |  |  |  |  | # for this, but we got reports that packaging PONAPI::Server
37 |  |  |  |  | # becomes hugely complex by adding either of those as dependencies.
38 |  |  |  |  | # Since this is just for testing, let's forgo a couple of good practices
39 |  |  |  |  | # and do it all manually.
40 |  |  |  |  | my @keys = keys %$values;
41 |  |  |  |  | my @values = values %$values;
42 |  |  |  |  | my $sql = "INSERT INTO $table " . (@keys
43 |  |  |  |  | ? '(' . join( ",", @keys) . ') VALUES (' . join(',', ('?') x @keys) . ')'
44 |  |  |  |  | : 'DEFAULT VALUES');
45 |  |  |  |  |
46 |  |  |  |  | my $stmt = {
47 |  |  |  |  | sql => $sql,
48 |  |  |  |  | bind => \@values,
49 |  |  |  |  | };
50 |  |  |  |  |
51 |  |  |  |  | return $stmt;
52 |  |  |  |  | }
53 |  |  |  |  |
54 |  |  |  |  | sub delete_stmt {
55 |  |  |  |  | my ($self, %args) = @_;
56 |  |  |  |  |
57 |  |  |  |  | my $table = $args{table};
58 |  |  |  |  | my $where = $args{where};
59 |  |  |  |  |
60 |  |  |  |  | my @keys = keys %$where;
61 |  |  |  |  | my @values = values %$where;
62 |  |  |  |  |
63 |  |  |  |  | my $sql = "DELETE FROM $table WHERE "
64 |  |  |  |  | . join " AND ", map "$_=?", @keys;
65 |  |  |  |  |
66 |  |  |  |  | my $stmt = { sql => $sql, bind => \@values };
67 |  |  |  |  |
68 |  |  |  |  | return $stmt;
69 |  |  |  |  | }
70 |  |  |  |  |
71 |  |  |  |  | # spent 24.5s (12.4+12.1) within Test::PONAPI::Repository::MockDB::Table::select_stmt which was called 368116 times, avg 67µs/call: # 187055 times (5.69s+5.16s) by Test::PONAPI::Repository::MockDB::_fetchall_relationships at line 728 of lib/Test/PONAPI/Repository/MockDB.pm, avg 58µs/call # 100001 times (4.09s+4.56s) by Test::PONAPI::Repository::MockDB::retrieve_all at line 88 of lib/Test/PONAPI/Repository/MockDB.pm, avg 86µs/call # 81060 times (2.58s+2.41s) by Test::PONAPI::Repository::MockDB::_add_included at line 675 of lib/Test/PONAPI/Repository/MockDB.pm, avg 62µs/call sub select_stmt {
72 | 368116 | 885ms |  |  | my ($self, %args) = @_;
73 |  |  |  |  |
74 | 368116 | 227ms |  |  | my $type = $args{type};
75 | 368116 | 867ms | 368116 | 7.22s | my $filters = $self->_stmt_filters($type, $args{filter}); # spent 7.22s making 368116 calls to Test::PONAPI::Repository::MockDB::Table::_stmt_filters, avg 20µs/call
76 |  |  |  |  |
77 | 368116 | 743ms |  |  | my %limit = %{ $args{page} || {} };
78 | 368116 | 277ms |  |  | my $sort = $args{sort} || [];
79 |  |  |  |  |
80 | 25306 | 284ms | 25306 | 131ms | my @order_by = map { # spent 131ms making 25306 calls to Test::PONAPI::Repository::MockDB::Table::CORE:match, avg 5µs/call
81 | 368116 | 352ms |  |  | my ($desc, $col) = /\A(-?)(.+)\z/s;
82 | 25306 | 58.1ms |  |  | join ' ', $col => uc( $desc ? 'desc' : 'asc' );
83 |  |  |  |  | } @$sort;
84 |  |  |  |  |
85 | 368116 | 937ms | 368116 | 4.78s | my $columns = $self->_stmt_columns(\%args); # spent 4.78s making 368116 calls to Test::PONAPI::Repository::MockDB::Table::_stmt_columns, avg 13µs/call
86 | 368116 | 876ms |  |  | my @values = map { ref($_) ? @$_ : $_ } values %$filters;
87 | 317871 | 173ms |  |  | my $sql = join "\n",
88 |  |  |  |  | 'SELECT ' . join(',', @$columns),
89 |  |  |  |  | 'FROM ' . $type,
90 |  |  |  |  | (%$filters
91 |  |  |  |  | ? 'WHERE ' . join(' AND ', map {
92 | 368116 | 1.95s |  |  | my $val = $filters->{$_};
93 |  |  |  |  | ref($val)
94 | 317871 | 380ms |  |  | ? "$_ IN (@{[ join ',', ('?') x @$val ]})"
95 |  |  |  |  | : "$_=?"
96 |  |  |  |  | } keys %$filters)
97 |  |  |  |  | : ''
98 |  |  |  |  | ),
99 |  |  |  |  | (@order_by ? 'ORDER BY ' . join(', ', @order_by) : ''),
100 |  |  |  |  | (%limit ? "LIMIT $limit{limit} OFFSET $limit{offset}" : '' );
101 |  |  |  |  |
102 | 368116 | 684ms |  |  | my $stmt = {
103 |  |  |  |  | sql => $sql,
104 |  |  |  |  | bind => \@values,
105 |  |  |  |  | };
106 |  |  |  |  |
107 | 368116 | 2.38s |  |  | return $stmt;
108 |  |  |  |  | }
109 |  |  |  |  |
110 |  |  |  |  | sub update_stmt {
111 |  |  |  |  | my ($self, %args) = @_;
112 |  |  |  |  |
113 |  |  |  |  | my $id = $args{id};
114 |  |  |  |  | my $table = $args{table};
115 |  |  |  |  | my $values = $args{values} || {};
116 |  |  |  |  | my $where = $args{where};
117 |  |  |  |  |
118 |  |  |  |  | my @cols = keys %$values;
119 |  |  |  |  | my @values = values %$values;
120 |  |  |  |  | push @values, values %$where;
121 |  |  |  |  |
122 |  |  |  |  | my $sql = join "\n",
123 |  |  |  |  | "UPDATE $table",
124 |  |  |  |  | "SET " . join(', ', map "$_=?", @cols),
125 |  |  |  |  | "WHERE " . join( ' AND ', map "$_=?", keys %$where );
126 |  |  |  |  |
127 |  |  |  |  | my $stmt = {
128 |  |  |  |  | sql => $sql,
129 |  |  |  |  | bind => \@values,
130 |  |  |  |  | };
131 |  |  |  |  |
132 |  |  |  |  | return $stmt;
133 |  |  |  |  | }
134 |  |  |  |  |
135 |  |  |  |  | # spent 4.78s (4.21+564ms) within Test::PONAPI::Repository::MockDB::Table::_stmt_columns which was called 368116 times, avg 13µs/call: # 368116 times (4.21s+564ms) by Test::PONAPI::Repository::MockDB::Table::select_stmt at line 85, avg 13µs/call sub _stmt_columns {
136 | 368116 | 135ms |  |  | my $self = shift;
137 | 368116 | 94.8ms |  |  | my $args = shift;
138 | 368116 | 467ms |  |  | my ( $fields, $type ) = @{$args}{qw< fields type >};
139 |  |  |  |  |
140 | 368116 | 165ms |  |  | my $ref = ref $fields;
141 |  |  |  |  |
142 | 368116 | 1.22s | 187055 | 219ms | return [ $self->ID_COLUMN, @$fields ] if $ref eq 'ARRAY'; # spent 219ms making 187055 calls to Test::PONAPI::Repository::MockDB::Table::ID_COLUMN, avg 1µs/call
143 |  |  |  |  |
144 | 181061 | 1.38s | 150192 | 117ms | $ref eq 'HASH' and exists $fields->{$type} # spent 86.0ms making 74135 calls to Test::PONAPI::Repository::MockDB::Table::COLUMNS, avg 1µs/call # spent 30.9ms making 76057 calls to Test::PONAPI::Repository::MockDB::Table::Articles::COLUMNS, avg 406ns/call
145 |  |  |  |  | or return $self->COLUMNS;
146 |  |  |  |  |
147 |  |  |  |  | my @fields_minus_relationship_keys =
148 |  |  |  |  | grep { !exists $self->RELATIONS->{$_} }
149 | 30869 | 186ms | 82744 | 125ms | @{ $fields->{$type} }; # spent 125ms making 82744 calls to Test::PONAPI::Repository::MockDB::Table::RELATIONS, avg 2µs/call
150 |  |  |  |  |
151 | 30869 | 309ms | 30869 | 103ms | return +[ $self->ID_COLUMN, @fields_minus_relationship_keys ]; # spent 103ms making 30869 calls to Test::PONAPI::Repository::MockDB::Table::ID_COLUMN, avg 3µs/call
152 |  |  |  |  | }
153 |  |  |  |  |
154 |  |  |  |  | # spent 7.22s (5.79+1.43) within Test::PONAPI::Repository::MockDB::Table::_stmt_filters which was called 368116 times, avg 20µs/call: # 368116 times (5.79s+1.43s) by Test::PONAPI::Repository::MockDB::Table::select_stmt at line 75, avg 20µs/call sub _stmt_filters {
155 | 368116 | 159ms |  |  | my ( $self, $type, $filter ) = @_;
156 |  |  |  |  |
157 | 368116 | 755ms | 368116 | 773ms | return $filter if $self->TABLE ne $type; # spent 773ms making 368116 calls to Test::PONAPI::Repository::MockDB::Table::TABLE, avg 2µs/call
158 |  |  |  |  |
159 |  |  |  |  | return +{
160 |  |  |  |  | map { $_ => $filter->{$_} }
161 |  |  |  |  | grep { exists $filter->{$_} }
162 | 368116 | 4.22s | 368116 | 660ms | @{ $self->COLUMNS } # spent 587ms making 275779 calls to Test::PONAPI::Repository::MockDB::Table::COLUMNS, avg 2µs/call # spent 73.3ms making 92337 calls to Test::PONAPI::Repository::MockDB::Table::Articles::COLUMNS, avg 794ns/call
163 |  |  |  |  | };
164 |  |  |  |  | }
165 |  |  |  |  |
166 | 1 | 5µs | 2 | 4.14ms | __PACKAGE__->meta->make_immutable; # spent 4.13ms making 1 call to Class::MOP::Class::make_immutable # spent 12µs making 1 call to Test::PONAPI::Repository::MockDB::Table::meta
167 | 3 | 49µs | 2 | 152µs | # spent 80µs (8+72) within Test::PONAPI::Repository::MockDB::Table::BEGIN@167 which was called: # once (8µs+72µs) by Module::Runtime::require_module at line 167 no Moose; 1; # spent 80µs making 1 call to Test::PONAPI::Repository::MockDB::Table::BEGIN@167 # spent 72µs making 1 call to Moose::unimport
168 |  |  |  |  |
169 |  |  |  |  | __END__