Filename | /home/tmurray/proj/Game-Collisions/lib/Game/Collisions.pm |
Statements | Executed 1111338 statements in 649ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
20000 | 1 | 1 | 1.54s | 2.12s | get_collisions_for_aabb | Game::Collisions::
20 | 1 | 1 | 60.7ms | 2.18s | get_collisions | Game::Collisions::
1000 | 1 | 1 | 18.8ms | 829ms | _add_aabb | Game::Collisions::
1000 | 1 | 1 | 4.56ms | 835ms | make_aabb | Game::Collisions::
999 | 1 | 1 | 1.59ms | 3.31ms | _new_meta_aabb | Game::Collisions::
1 | 1 | 1 | 1.28ms | 4.16ms | BEGIN@30 | Game::Collisions::
1 | 1 | 1 | 823µs | 1.13ms | BEGIN@28 | Game::Collisions::
1 | 1 | 1 | 20µs | 20µs | BEGIN@26 | Game::Collisions::
1 | 1 | 1 | 9µs | 15µs | BEGIN@27 | Game::Collisions::
1 | 1 | 1 | 7µs | 7µs | new | Game::Collisions::
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 # 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 # 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 # 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 # 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__ |