Profile of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions.pm

← Index
NYTProf Performance Profile «line view»
For scripts/bench.pl
Run on Mon Oct 22 16:48:56 2018
Reported on Mon Oct 22 16:49:10 2018

Filename | /home/tmurray/proj/Game-Collisions/lib/Game/Collisions.pm
Statements | Executed 1111338 statements in 649ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
20000 | 1 | 1 | 1.54s | 2.12s | Game::Collisions::::get_collisions_for_aabbGame::Collisions::get_collisions_for_aabb
20 | 1 | 1 | 60.7ms | 2.18s | Game::Collisions::::get_collisionsGame::Collisions::get_collisions
1000 | 1 | 1 | 18.8ms | 829ms | Game::Collisions::::_add_aabbGame::Collisions::_add_aabb
1000 | 1 | 1 | 4.56ms | 835ms | Game::Collisions::::make_aabbGame::Collisions::make_aabb
999 | 1 | 1 | 1.59ms | 3.31ms | Game::Collisions::::_new_meta_aabbGame::Collisions::_new_meta_aabb
1 | 1 | 1 | 1.28ms | 4.16ms | Game::Collisions::::BEGIN@30Game::Collisions::BEGIN@30
1 | 1 | 1 | 823µs | 1.13ms | Game::Collisions::::BEGIN@28Game::Collisions::BEGIN@28
1 | 1 | 1 | 20µs | 20µs | Game::Collisions::::BEGIN@26Game::Collisions::BEGIN@26
1 | 1 | 1 | 9µs | 15µs | Game::Collisions::::BEGIN@27Game::Collisions::BEGIN@27
1 | 1 | 1 | 7µs | 7µs | Game::Collisions::::newGame::Collisions::new

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | # Copyright (c) 2018 Timm Murray
2 |  |  |  |  | # All rights reserved.
3 |  |  |  |  | #
4 |  |  |  |  | # Redistribution and use in source and binary forms, with or without
5 |  |  |  |  | # modification, are permitted provided that the following conditions are met:
6 |  |  |  |  | #
7 |  |  |  |  | # * Redistributions of source code must retain the above copyright notice,
8 |  |  |  |  | # this list of conditions and the following disclaimer.
9 |  |  |  |  | # * Redistributions in binary form must reproduce the above copyright
10 |  |  |  |  | # notice, this list of conditions and the following disclaimer in the
11 |  |  |  |  | # documentation and/or other materials provided with the distribution.
12 |  |  |  |  | #
13 |  |  |  |  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 |  |  |  |  | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 |  |  |  |  | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 |  |  |  |  | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17 |  |  |  |  | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 |  |  |  |  | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 |  |  |  |  | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 |  |  |  |  | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 |  |  |  |  | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 |  |  |  |  | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 |  |  |  |  | # POSSIBILITY OF SUCH DAMAGE.
24 |  |  |  |  | package Game::Collisions;
25 |  |  |  |  |
26 | 2 | 53µs | 1 | 20µs | # spent 20µs within Game::Collisions::BEGIN@26 which was called: # once (20µs+0s) by main::BEGIN@28 at line 26 use v5.14; # spent 20µs making 1 call to Game::Collisions::BEGIN@26
27 | 2 | 24µs | 2 | 21µs | # spent 15µs (9+6) within Game::Collisions::BEGIN@27 which was called: # once (9µs+6µs) by main::BEGIN@28 at line 27 use warnings; # spent 15µs making 1 call to Game::Collisions::BEGIN@27 # spent 6µs making 1 call to warnings::import
28 | 2 | 160µs | 1 | 1.13ms | # spent 1.13ms (823µs+312µs) within Game::Collisions::BEGIN@28 which was called: # once (823µs+312µs) by main::BEGIN@28 at line 28 use List::Util (); # spent 1.13ms making 1 call to Game::Collisions::BEGIN@28
29 |  |  |  |  |
30 | 2 | 532µs | 1 | 4.16ms | # spent 4.16ms (1.28+2.88) within Game::Collisions::BEGIN@30 which was called: # once (1.28ms+2.88ms) by main::BEGIN@28 at line 30 use Game::Collisions::AABB; # spent 4.16ms making 1 call to Game::Collisions::BEGIN@30
31 |  |  |  |  |
32 |  |  |  |  | # ABSTRACT: Collision detection in 2D space
33 |  |  |  |  |
34 |  |  |  |  |
35 |  |  |  |  | sub new
36 |  |  |  |  | # spent 7µs within Game::Collisions::new which was called: # once (7µs+0s) by main::RUNTIME at line 6038 of /home/tmurray/proj/Game-Collisions/scripts/bench.pl {
37 | 1 | 700ns |  |  | my ($class) = @_;
38 | 1 | 2µs |  |  | my $self = {
39 |  |  |  |  | root_aabb => undef,
40 |  |  |  |  | complete_aabb_list => [],
41 |  |  |  |  | };
42 | 1 | 800ns |  |  | bless $self => $class;
43 |  |  |  |  |
44 |  |  |  |  |
45 | 1 | 7µs |  |  | return $self;
46 |  |  |  |  | }
47 |  |  |  |  |
48 |  |  |  |  |
49 |  |  |  |  | sub make_aabb
50 |  |  |  |  | # spent 835ms (4.56+831) within Game::Collisions::make_aabb which was called 1000 times, avg 835µs/call: # 1000 times (4.56ms+831ms) by main::RUNTIME at line 6039 of /home/tmurray/proj/Game-Collisions/scripts/bench.pl, avg 835µs/call {
51 | 1000 | 140µs |  |  | my ($self, $args) = @_;
52 | 1000 | 614µs | 1000 | 1.61ms | my $aabb = Game::Collisions::AABB->new( $args ); # spent 1.61ms making 1000 calls to Game::Collisions::AABB::new, avg 2µs/call
53 | 1000 | 510µs | 1000 | 829ms | $self->_add_aabb( $aabb ); # spent 829ms making 1000 calls to Game::Collisions::_add_aabb, avg 829µs/call
54 | 1000 | 876µs |  |  | return $aabb;
55 |  |  |  |  | }
56 |  |  |  |  |
57 |  |  |  |  | sub get_collisions
58 |  |  |  |  | # spent 2.18s (60.7ms+2.12) within Game::Collisions::get_collisions which was called 20 times, avg 109ms/call: # 20 times (60.7ms+2.12s) by main::RUNTIME at line 6042 of /home/tmurray/proj/Game-Collisions/scripts/bench.pl, avg 109ms/call {
59 | 20 | 18µs |  |  | my ($self) = @_;
60 | 20 | 1.49ms |  |  | my @aabbs_to_check = @{ $self->{complete_aabb_list} };
61 | 20 | 5µs |  |  | my @collisions;
62 |  |  |  |  |
63 | 20 | 29µs |  |  | foreach my $aabb (@aabbs_to_check) {
64 | 20000 | 18.9ms | 20000 | 2.12s | push @collisions => $self->get_collisions_for_aabb( $aabb ); # spent 2.12s making 20000 calls to Game::Collisions::get_collisions_for_aabb, avg 106µs/call
65 |  |  |  |  | }
66 |  |  |  |  |
67 | 20 | 2.76ms |  |  | return @collisions;
68 |  |  |  |  | }
69 |  |  |  |  |
70 |  |  |  |  | sub get_collisions_for_aabb
71 |  |  |  |  | # spent 2.12s (1.54+576ms) within Game::Collisions::get_collisions_for_aabb which was called 20000 times, avg 106µs/call: # 20000 times (1.54s+576ms) by Game::Collisions::get_collisions at line 64, avg 106µs/call {
72 | 20000 | 2.96ms |  |  | my ($self, $aabb) = @_;
73 | 20000 | 5.53ms |  |  | return () if ! defined $self->{root_aabb};
74 | 20000 | 1.57ms |  |  | my @collisions;
75 |  |  |  |  |
76 | 20000 | 5.54ms |  |  | my @nodes_to_check = ($self->{root_aabb});
77 | 20000 | 6.52ms |  |  | while( @nodes_to_check ) {
78 | 194280 | 24.0ms |  |  | my $check_node = shift @nodes_to_check;
79 |  |  |  |  |
80 | 194280 | 175ms | 194280 | 105ms | if( $check_node->is_branch_node ) { # spent 105ms making 194280 calls to Game::Collisions::AABB::is_branch_node, avg 539ns/call
81 | 183200 | 95.0ms | 183200 | 58.4ms | my $left_node = $check_node->left_node; # spent 58.4ms making 183200 calls to Game::Collisions::AABB::left_node, avg 319ns/call
82 | 183200 | 90.0ms | 183200 | 59.4ms | my $right_node = $check_node->right_node; # spent 59.4ms making 183200 calls to Game::Collisions::AABB::right_node, avg 324ns/call
83 |  |  |  |  |
84 | 183200 | 151ms | 239960 | 354ms | if( $left_node->does_collide( $aabb ) ) { # spent 354ms making 239960 calls to Game::Collisions::AABB::does_collide, avg 1µs/call
85 |  |  |  |  | push @nodes_to_check, $left_node;
86 |  |  |  |  | }
87 |  |  |  |  | elsif( $right_node->does_collide( $aabb ) ) {
88 |  |  |  |  | push @nodes_to_check, $right_node;
89 |  |  |  |  | }
90 |  |  |  |  | }
91 |  |  |  |  | else {
92 |  |  |  |  | # We already know it collided, since it wouldn't be added
93 |  |  |  |  | # to @nodes_to_check otherwise.
94 | 11080 | 3.97ms |  |  | push @collisions, [ $aabb, $check_node ];
95 |  |  |  |  | }
96 |  |  |  |  | }
97 |  |  |  |  |
98 | 20000 | 47.0ms |  |  | return @collisions;
99 |  |  |  |  | }
100 |  |  |  |  |
101 |  |  |  |  |
102 |  |  |  |  | sub _add_aabb
103 |  |  |  |  | # spent 829ms (18.8+810) within Game::Collisions::_add_aabb which was called 1000 times, avg 829µs/call: # 1000 times (18.8ms+810ms) by Game::Collisions::make_aabb at line 53, avg 829µs/call {
104 | 1000 | 122µs |  |  | my ($self, $new_node) = @_;
105 | 1000 | 200µs |  |  | if(! defined $self->{root_aabb} ) {
106 | 1 | 500ns |  |  | $self->{root_aabb} = $new_node;
107 | 1 | 1µs |  |  | push @{ $self->{complete_aabb_list} }, $new_node;
108 | 1 | 3µs |  |  | return;
109 |  |  |  |  | }
110 |  |  |  |  |
111 | 999 | 653µs | 999 | 469ms | my $best_sibling = $self->{root_aabb}->find_best_sibling_node( $new_node ); # spent 469ms making 999 calls to Game::Collisions::AABB::find_best_sibling_node, avg 470µs/call
112 |  |  |  |  |
113 | 999 | 1.68ms | 2997 | 758µs | my $min_x = List::Util::min( $new_node->x, $best_sibling->x ); # spent 561µs making 1998 calls to Game::Collisions::AABB::x, avg 281ns/call # spent 198µs making 999 calls to List::Util::min, avg 198ns/call
114 | 999 | 1.58ms | 2997 | 636µs | my $min_y = List::Util::min( $new_node->y, $best_sibling->y ); # spent 499µs making 1998 calls to Game::Collisions::AABB::y, avg 250ns/call # spent 137µs making 999 calls to List::Util::min, avg 137ns/call
115 |  |  |  |  |
116 | 999 | 1.50ms | 999 | 3.31ms | my $new_branch = $self->_new_meta_aabb({ # spent 3.31ms making 999 calls to Game::Collisions::_new_meta_aabb, avg 3µs/call
117 |  |  |  |  | x => $min_x,
118 |  |  |  |  | y => $min_y,
119 |  |  |  |  | length => 1,
120 |  |  |  |  | height => 1,
121 |  |  |  |  | });
122 |  |  |  |  |
123 | 999 | 539µs | 999 | 351µs | my $old_parent = $best_sibling->parent; # spent 351µs making 999 calls to Game::Collisions::AABB::parent, avg 352ns/call
124 | 999 | 456µs | 999 | 8.73ms | $new_branch->set_left_node( $new_node ); # spent 8.73ms making 999 calls to Game::Collisions::AABB::set_left_node, avg 9µs/call
125 | 999 | 445µs | 999 | 6.36ms | $new_branch->set_right_node( $best_sibling ); # spent 6.36ms making 999 calls to Game::Collisions::AABB::set_right_node, avg 6µs/call
126 |  |  |  |  |
127 | 999 | 252µs |  |  | if(! defined $old_parent ) {
128 |  |  |  |  | # Happens when the root is going to be the new sibling. In this case,
129 |  |  |  |  | # create a new node for the root.
130 |  |  |  |  | $self->{root_aabb} = $new_branch;
131 |  |  |  |  | }
132 |  |  |  |  | else {
133 | 998 | 718µs | 998 | 336µs | my $set_method = $best_sibling == $old_parent->left_node # spent 336µs making 998 calls to Game::Collisions::AABB::left_node, avg 337ns/call
134 |  |  |  |  | ? "set_left_node"
135 |  |  |  |  | : "set_right_node";
136 | 998 | 851µs | 998 | 5.32ms | $old_parent->$set_method( $new_branch ); # spent 2.91ms making 542 calls to Game::Collisions::AABB::set_left_node, avg 5µs/call # spent 2.41ms making 456 calls to Game::Collisions::AABB::set_right_node, avg 5µs/call
137 |  |  |  |  | }
138 |  |  |  |  |
139 | 999 | 455µs | 999 | 315ms | $new_branch->resize_all_parents; # spent 315ms making 999 calls to Game::Collisions::AABB::resize_all_parents, avg 316µs/call
140 | 999 | 328µs |  |  | push @{ $self->{complete_aabb_list} }, $new_node;
141 | 999 | 3.06ms |  |  | return;
142 |  |  |  |  | }
143 |  |  |  |  |
144 |  |  |  |  | sub _new_meta_aabb
145 |  |  |  |  | # spent 3.31ms (1.59+1.71) within Game::Collisions::_new_meta_aabb which was called 999 times, avg 3µs/call: # 999 times (1.59ms+1.71ms) by Game::Collisions::_add_aabb at line 116, avg 3µs/call {
146 | 999 | 139µs |  |  | my ($self, $args) = @_;
147 | 999 | 597µs | 999 | 1.71ms | my $aabb = Game::Collisions::AABB->new( $args ); # spent 1.71ms making 999 calls to Game::Collisions::AABB::new, avg 2µs/call
148 | 999 | 738µs |  |  | return $aabb;
149 |  |  |  |  | }
150 |  |  |  |  |
151 |  |  |  |  |
152 | 1 | 2µs |  |  | 1;
153 |  |  |  |  | __END__