Profile of constant.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 | /usr/share/perl/5.26/constant.pm
Statements | Executed 362 statements in 1.85ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
11 | 11 | 2 | 232µs | 288µs | constant::::importconstant::import
1 | 1 | 1 | 29µs | 31µs | constant::::BEGIN@24constant::BEGIN@24
11 | 1 | 1 | 16µs | 16µs | constant::::CORE:substconstant::CORE:subst (opcode)
1 | 1 | 1 | 16µs | 16µs | constant::::BEGIN@2constant::BEGIN@2
11 | 1 | 1 | 14µs | 14µs | constant::::CORE:matchconstant::CORE:match (opcode)
11 | 1 | 1 | 12µs | 12µs | constant::::CORE:regcompconstant::CORE:regcomp (opcode)
1 | 1 | 1 | 9µs | 19µs | constant::::BEGIN@141constant::BEGIN@141
1 | 1 | 1 | 8µs | 21µs | constant::::BEGIN@40constant::BEGIN@40
1 | 1 | 1 | 8µs | 11µs | constant::::BEGIN@3constant::BEGIN@3
1 | 1 | 1 | 7µs | 18µs | constant::::BEGIN@65constant::BEGIN@65
1 | 1 | 1 | 7µs | 22µs | constant::::BEGIN@90constant::BEGIN@90
1 | 1 | 1 | 6µs | 91µs | constant::::BEGIN@4constant::BEGIN@4
3 | 3 | 1 | 3µs | 3µs | constant::::CORE:qrconstant::CORE:qr (opcode)
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:174]constant::__ANON__[:174]
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:190]constant::__ANON__[:190]
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:192]constant::__ANON__[:192]
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:41]constant::__ANON__[:41]
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:42]constant::__ANON__[:42]
0 | 0 | 0 | 0s | 0s | constant::::__ANON__[:43]constant::__ANON__[:43]

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package constant;
2 | 2 | 44µs | 1 | 16µs | # spent 16µs within constant::BEGIN@2 which was called: # once (16µs+0s) by Game::Collisions::AABB::BEGIN@32 at line 2 use 5.008; # spent 16µs making 1 call to constant::BEGIN@2
3 | 2 | 23µs | 2 | 15µs | # spent 11µs (8+3) within constant::BEGIN@3 which was called: # once (8µs+3µs) by Game::Collisions::AABB::BEGIN@32 at line 3 use strict; # spent 11µs making 1 call to constant::BEGIN@3 # spent 3µs making 1 call to strict::import
4 | 2 | 324µs | 2 | 177µs | # spent 91µs (6+86) within constant::BEGIN@4 which was called: # once (6µs+86µs) by Game::Collisions::AABB::BEGIN@32 at line 4 use warnings::register; # spent 91µs making 1 call to constant::BEGIN@4 # spent 86µs making 1 call to warnings::register::import
5 |  |  |  |  |
6 | 1 | 400ns |  |  | our $VERSION = '1.33';
7 |  |  |  |  | our %declared;
8 |  |  |  |  |
9 |  |  |  |  | #=======================================================================
10 |  |  |  |  |
11 |  |  |  |  | # Some names are evil choices.
12 | 1 | 5µs |  |  | my %keywords = map +($_, 1), qw{ BEGIN INIT CHECK END DESTROY AUTOLOAD };
13 | 1 | 1µs |  |  | $keywords{UNITCHECK}++ if $] > 5.009;
14 |  |  |  |  |
15 | 1 | 4µs |  |  | my %forced_into_main = map +($_, 1),
16 |  |  |  |  | qw{ STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG };
17 |  |  |  |  |
18 | 1 | 5µs |  |  | my %forbidden = (%keywords, %forced_into_main);
19 |  |  |  |  |
20 | 1 | 8µs | 1 | 2µs | my $normal_constant_name = qr/^_?[^\W_0-9]\w*\z/; # spent 2µs making 1 call to constant::CORE:qr
21 | 1 | 2µs | 1 | 600ns | my $tolerable = qr/^[A-Za-z_]\w*\z/; # spent 600ns making 1 call to constant::CORE:qr
22 | 1 | 2µs | 1 | 400ns | my $boolean = qr/^[01]?\z/; # spent 400ns making 1 call to constant::CORE:qr
23 |  |  |  |  |
24 |  |  |  |  | # spent 31µs (29+2) within constant::BEGIN@24 which was called: # once (29µs+2µs) by Game::Collisions::AABB::BEGIN@32 at line 45 BEGIN {
25 |  |  |  |  | # We'd like to do use constant _CAN_PCS => $] > 5.009002
26 |  |  |  |  | # but that's a bit tricky before we load the constant module :-)
27 |  |  |  |  | # By doing this, we save several run time checks for *every* call
28 |  |  |  |  | # to import.
29 | 1 | 1µs |  |  | my $const = $] > 5.009002;
30 | 1 | 600ns |  |  | my $downgrade = $] < 5.015004; # && $] >= 5.008
31 | 1 | 600ns |  |  | my $constarray = exists &_make_const;
32 | 1 | 3µs |  |  | if ($const) {
33 | 1 | 19µs | 1 | 1µs | Internals::SvREADONLY($const, 1); # spent 1µs making 1 call to Internals::SvREADONLY
34 | 1 | 3µs | 1 | 500ns | Internals::SvREADONLY($downgrade, 1); # spent 500ns making 1 call to Internals::SvREADONLY
35 | 1 | 2µs |  |  | $constant::{_CAN_PCS} = \$const;
36 | 1 | 500ns |  |  | $constant::{_DOWNGRADE} = \$downgrade;
37 | 1 | 600ns |  |  | $constant::{_CAN_PCS_FOR_ARRAY} = \$constarray;
38 |  |  |  |  | }
39 |  |  |  |  | else {
40 | 2 | 103µs | 2 | 34µs | # spent 21µs (8+13) within constant::BEGIN@40 which was called: # once (8µs+13µs) by Game::Collisions::AABB::BEGIN@32 at line 40 no strict 'refs'; # spent 21µs making 1 call to constant::BEGIN@40 # spent 13µs making 1 call to strict::unimport
41 |  |  |  |  | *{"_CAN_PCS"} = sub () {$const};
42 |  |  |  |  | *{"_DOWNGRADE"} = sub () { $downgrade };
43 |  |  |  |  | *{"_CAN_PCS_FOR_ARRAY"} = sub () { $constarray };
44 |  |  |  |  | }
45 | 1 | 88µs | 1 | 31µs | } # spent 31µs making 1 call to constant::BEGIN@24
46 |  |  |  |  |
47 |  |  |  |  | #=======================================================================
48 |  |  |  |  | # import() - import symbols into user's namespace
49 |  |  |  |  | #
50 |  |  |  |  | # What we actually do is define a function in the caller's namespace
51 |  |  |  |  | # which returns the value. The function we create will normally
52 |  |  |  |  | # be inlined as a constant, thereby avoiding further sub calling
53 |  |  |  |  | # overhead.
54 |  |  |  |  | #=======================================================================
55 |  |  |  |  | # spent 288µs (232+56) within constant::import which was called 11 times, avg 26µs/call: # once (32µs+10µs) by Game::Collisions::AABB::BEGIN@32 at line 32 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (26µs+10µs) by main::BEGIN@30 at line 30 of /home/tmurray/proj/Game-Collisions/scripts/bench.pl # once (28µs+5µs) by Game::Collisions::AABB::BEGIN@34 at line 34 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (21µs+6µs) by Game::Collisions::AABB::BEGIN@33 at line 33 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (21µs+5µs) by main::BEGIN@31 at line 31 of /home/tmurray/proj/Game-Collisions/scripts/bench.pl # once (20µs+4µs) by Game::Collisions::AABB::BEGIN@36 at line 36 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (18µs+4µs) by Game::Collisions::AABB::BEGIN@35 at line 35 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (18µs+3µs) by Game::Collisions::AABB::BEGIN@38 at line 38 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (17µs+3µs) by Game::Collisions::AABB::BEGIN@39 at line 39 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (16µs+4µs) by Game::Collisions::AABB::BEGIN@37 at line 37 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm # once (16µs+3µs) by Game::Collisions::AABB::BEGIN@40 at line 40 of /home/tmurray/proj/Game-Collisions/lib/Game/Collisions/AABB.pm sub import {
56 | 11 | 3µs |  |  | my $class = shift;
57 | 11 | 3µs |  |  | return unless @_; # Ignore 'use constant;'
58 | 11 | 1µs |  |  | my $constants;
59 | 11 | 4µs |  |  | my $multiple = ref $_[0];
60 | 11 | 4µs |  |  | my $caller = caller;
61 | 11 | 2µs |  |  | my $flush_mro;
62 |  |  |  |  | my $symtab;
63 |  |  |  |  |
64 | 11 | 3µs |  |  | if (_CAN_PCS) {
65 | 2 | 166µs | 2 | 28µs | # spent 18µs (7+11) within constant::BEGIN@65 which was called: # once (7µs+11µs) by Game::Collisions::AABB::BEGIN@32 at line 65 no strict 'refs'; # spent 18µs making 1 call to constant::BEGIN@65 # spent 11µs making 1 call to strict::unimport
66 | 11 | 11µs |  |  | $symtab = \%{$caller . '::'};
67 |  |  |  |  | };
68 |  |  |  |  |
69 | 11 | 3µs |  |  | if ( $multiple ) {
70 |  |  |  |  | if (ref $_[0] ne 'HASH') {
71 |  |  |  |  | require Carp;
72 |  |  |  |  | Carp::croak("Invalid reference type '".ref(shift)."' not 'HASH'");
73 |  |  |  |  | }
74 |  |  |  |  | $constants = shift;
75 |  |  |  |  | } else {
76 | 11 | 2µs |  |  | unless (defined $_[0]) {
77 |  |  |  |  | require Carp;
78 |  |  |  |  | Carp::croak("Can't use undef as constant name");
79 |  |  |  |  | }
80 | 11 | 11µs |  |  | $constants->{+shift} = undef;
81 |  |  |  |  | }
82 |  |  |  |  |
83 | 11 | 11µs |  |  | foreach my $name ( keys %$constants ) {
84 | 11 | 1µs |  |  | my $pkg;
85 | 11 | 2µs |  |  | my $symtab = $symtab;
86 | 11 | 2µs |  |  | my $orig_name = $name;
87 | 11 | 40µs | 11 | 16µs | if ($name =~ s/(.*)(?:::|')(?=.)//s) { # spent 16µs making 11 calls to constant::CORE:subst, avg 1µs/call
88 |  |  |  |  | $pkg = $1;
89 |  |  |  |  | if (_CAN_PCS && $pkg ne $caller) {
90 | 2 | 233µs | 2 | 37µs | # spent 22µs (7+15) within constant::BEGIN@90 which was called: # once (7µs+15µs) by Game::Collisions::AABB::BEGIN@32 at line 90 no strict 'refs'; # spent 22µs making 1 call to constant::BEGIN@90 # spent 15µs making 1 call to strict::unimport
91 |  |  |  |  | $symtab = \%{$pkg . '::'};
92 |  |  |  |  | }
93 |  |  |  |  | }
94 |  |  |  |  | else {
95 | 11 | 2µs |  |  | $pkg = $caller;
96 |  |  |  |  | }
97 |  |  |  |  |
98 |  |  |  |  | # Normal constant name
99 | 11 | 62µs | 22 | 26µs | if ($name =~ $normal_constant_name and !$forbidden{$name}) { # spent 14µs making 11 calls to constant::CORE:match, avg 1µs/call # spent 12µs making 11 calls to constant::CORE:regcomp, avg 1µs/call
100 |  |  |  |  | # Everything is okay
101 |  |  |  |  |
102 |  |  |  |  | # Name forced into main, but we're not in main. Fatal.
103 |  |  |  |  | } elsif ($forced_into_main{$name} and $pkg ne 'main') {
104 |  |  |  |  | require Carp;
105 |  |  |  |  | Carp::croak("Constant name '$name' is forced into main::");
106 |  |  |  |  |
107 |  |  |  |  | # Starts with double underscore. Fatal.
108 |  |  |  |  | } elsif ($name =~ /^__/) {
109 |  |  |  |  | require Carp;
110 |  |  |  |  | Carp::croak("Constant name '$name' begins with '__'");
111 |  |  |  |  |
112 |  |  |  |  | # Maybe the name is tolerable
113 |  |  |  |  | } elsif ($name =~ $tolerable) {
114 |  |  |  |  | # Then we'll warn only if you've asked for warnings
115 |  |  |  |  | if (warnings::enabled()) {
116 |  |  |  |  | if ($keywords{$name}) {
117 |  |  |  |  | warnings::warn("Constant name '$name' is a Perl keyword");
118 |  |  |  |  | } elsif ($forced_into_main{$name}) {
119 |  |  |  |  | warnings::warn("Constant name '$name' is " .
120 |  |  |  |  | "forced into package main::");
121 |  |  |  |  | }
122 |  |  |  |  | }
123 |  |  |  |  |
124 |  |  |  |  | # Looks like a boolean
125 |  |  |  |  | # use constant FRED == fred;
126 |  |  |  |  | } elsif ($name =~ $boolean) {
127 |  |  |  |  | require Carp;
128 |  |  |  |  | if (@_) {
129 |  |  |  |  | Carp::croak("Constant name '$name' is invalid");
130 |  |  |  |  | } else {
131 |  |  |  |  | Carp::croak("Constant name looks like boolean value");
132 |  |  |  |  | }
133 |  |  |  |  |
134 |  |  |  |  | } else {
135 |  |  |  |  | # Must have bad characters
136 |  |  |  |  | require Carp;
137 |  |  |  |  | Carp::croak("Constant name '$name' has invalid characters");
138 |  |  |  |  | }
139 |  |  |  |  |
140 |  |  |  |  | {
141 | 13 | 467µs | 2 | 29µs | # spent 19µs (9+10) within constant::BEGIN@141 which was called: # once (9µs+10µs) by Game::Collisions::AABB::BEGIN@32 at line 141 no strict 'refs'; # spent 19µs making 1 call to constant::BEGIN@141 # spent 10µs making 1 call to strict::unimport
142 | 11 | 6µs |  |  | my $full_name = "${pkg}::$name";
143 | 11 | 7µs |  |  | $declared{$full_name}++;
144 | 11 | 6µs |  |  | if ($multiple || @_ == 1) {
145 | 11 | 3µs |  |  | my $scalar = $multiple ? $constants->{$orig_name} : $_[0];
146 |  |  |  |  |
147 |  |  |  |  | if (_DOWNGRADE) { # for 5.8 to 5.14
148 |  |  |  |  | # Work around perl bug #31991: Sub names (actually glob
149 |  |  |  |  | # names in general) ignore the UTF8 flag. So we have to
150 |  |  |  |  | # turn it off to get the "right" symbol table entry.
151 |  |  |  |  | utf8::is_utf8 $name and utf8::encode $name;
152 |  |  |  |  | }
153 |  |  |  |  |
154 |  |  |  |  | # The constant serves to optimise this entire block out on
155 |  |  |  |  | # 5.8 and earlier.
156 | 11 | 3µs |  |  | if (_CAN_PCS) {
157 |  |  |  |  | # Use a reference as a proxy for a constant subroutine.
158 |  |  |  |  | # If this is not a glob yet, it saves space. If it is
159 |  |  |  |  | # a glob, we must still create it this way to get the
160 |  |  |  |  | # right internal flags set, as constants are distinct
161 |  |  |  |  | # from subroutines created with sub(){...}.
162 |  |  |  |  | # The check in Perl_ck_rvconst knows that inlinable
163 |  |  |  |  | # constants from cv_const_sv are read only. So we have to:
164 | 11 | 21µs | 11 | 6µs | Internals::SvREADONLY($scalar, 1); # spent 6µs making 11 calls to Internals::SvREADONLY, avg 509ns/call
165 | 11 | 6µs |  |  | if (!exists $symtab->{$name}) {
166 | 11 | 5µs |  |  | $symtab->{$name} = \$scalar;
167 | 11 | 6µs |  |  | ++$flush_mro->{$pkg};
168 |  |  |  |  | }
169 |  |  |  |  | else {
170 |  |  |  |  | local $constant::{_dummy} = \$scalar;
171 |  |  |  |  | *$full_name = \&{"_dummy"};
172 |  |  |  |  | }
173 |  |  |  |  | } else {
174 |  |  |  |  | *$full_name = sub () { $scalar };
175 |  |  |  |  | }
176 |  |  |  |  | } elsif (@_) {
177 |  |  |  |  | my @list = @_;
178 |  |  |  |  | if (_CAN_PCS_FOR_ARRAY) {
179 |  |  |  |  | _make_const($list[$_]) for 0..$#list;
180 |  |  |  |  | _make_const(@list);
181 |  |  |  |  | if (!exists $symtab->{$name}) {
182 |  |  |  |  | $symtab->{$name} = \@list;
183 |  |  |  |  | $flush_mro->{$pkg}++;
184 |  |  |  |  | }
185 |  |  |  |  | else {
186 |  |  |  |  | local $constant::{_dummy} = \@list;
187 |  |  |  |  | *$full_name = \&{"_dummy"};
188 |  |  |  |  | }
189 |  |  |  |  | }
190 |  |  |  |  | else { *$full_name = sub () { @list }; }
191 |  |  |  |  | } else {
192 |  |  |  |  | *$full_name = sub () { };
193 |  |  |  |  | }
194 |  |  |  |  | }
195 |  |  |  |  | }
196 |  |  |  |  | # Flush the cache exactly once if we make any direct symbol table changes.
197 | 11 | 77µs |  |  | if (_CAN_PCS && $flush_mro) {
198 | 11 | 35µs | 11 | 8µs | mro::method_changed_in($_) for keys %$flush_mro; # spent 8µs making 11 calls to mro::method_changed_in, avg 764ns/call
199 |  |  |  |  | }
200 |  |  |  |  | }
201 |  |  |  |  |
202 | 1 | 9µs |  |  | 1;
203 |  |  |  |  |
204 |  |  |  |  | __END__
|  |  |  |  | # spent 14µs within constant::CORE:match which was called 11 times, avg 1µs/call: # 11 times (14µs+0s) by constant::import at line 99, avg 1µs/call sub constant::CORE:match; # opcode
|  |  |  |  | # spent 3µs within constant::CORE:qr which was called 3 times, avg 1µs/call: # once (2µs+0s) by Game::Collisions::AABB::BEGIN@32 at line 20 # once (600ns+0s) by Game::Collisions::AABB::BEGIN@32 at line 21 # once (400ns+0s) by Game::Collisions::AABB::BEGIN@32 at line 22 sub constant::CORE:qr; # opcode
|  |  |  |  | # spent 12µs within constant::CORE:regcomp which was called 11 times, avg 1µs/call: # 11 times (12µs+0s) by constant::import at line 99, avg 1µs/call sub constant::CORE:regcomp; # opcode
|  |  |  |  | # spent 16µs within constant::CORE:subst which was called 11 times, avg 1µs/call: # 11 times (16µs+0s) by constant::import at line 87, avg 1µs/call sub constant::CORE:subst; # opcode