Profile of constant.pm

← Index
NYTProf Performance Profile «line view»
For -e
Run on Thu Jun 30 16:16:00 2016
Reported on Thu Jun 30 16:16:08 2016

Filename | /home/s1/perl5/perlbrew/perls/perl-5.22.1/lib/5.22.1/constant.pm
Statements | Executed 689 statements in 3.18ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
22 | 22 | 5 | 775µs | 996µs | constant::::importconstant::import
22 | 1 | 1 | 67µs | 67µs | constant::::CORE:substconstant::CORE:subst (opcode)
22 | 1 | 1 | 57µs | 57µs | constant::::CORE:matchconstant::CORE:match (opcode)
22 | 1 | 1 | 45µs | 45µs | constant::::CORE:regcompconstant::CORE:regcomp (opcode)
1 | 1 | 1 | 24µs | 24µs | constant::::BEGIN@2constant::BEGIN@2
1 | 1 | 1 | 22µs | 24µs | constant::::BEGIN@24constant::BEGIN@24
1 | 1 | 1 | 12µs | 26µs | constant::::BEGIN@90constant::BEGIN@90
1 | 1 | 1 | 11µs | 28µs | constant::::BEGIN@40constant::BEGIN@40
1 | 1 | 1 | 11µs | 14µs | constant::::BEGIN@3constant::BEGIN@3
1 | 1 | 1 | 10µs | 24µs | constant::::BEGIN@141constant::BEGIN@141
1 | 1 | 1 | 10µs | 24µs | constant::::BEGIN@65constant::BEGIN@65
1 | 1 | 1 | 9µs | 111µs | constant::::BEGIN@4constant::BEGIN@4
3 | 3 | 1 | 4µs | 4µ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 | 67µs | 1 | 24µs | # spent 24µs within constant::BEGIN@2 which was called: # once (24µs+0s) by Try::Tiny::ScopeGuard::BEGIN@161 at line 2 use 5.008; # spent 24µs making 1 call to constant::BEGIN@2
3 | 2 | 36µs | 2 | 18µs | # spent 14µs (11+3) within constant::BEGIN@3 which was called: # once (11µs+3µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 3 use strict; # spent 14µs making 1 call to constant::BEGIN@3 # spent 4µs making 1 call to strict::import
4 | 2 | 728µs | 2 | 213µs | # spent 111µs (9+102) within constant::BEGIN@4 which was called: # once (9µs+102µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 4 use warnings::register; # spent 111µs making 1 call to constant::BEGIN@4 # spent 102µs making 1 call to warnings::register::import
5 |  |  |  |  |
6 | 1 | 600ns |  |  | our $VERSION = '1.33';
7 |  |  |  |  | our %declared;
8 |  |  |  |  |
9 |  |  |  |  | #=======================================================================
10 |  |  |  |  |
11 |  |  |  |  | # Some names are evil choices.
12 | 1 | 8µs |  |  | my %keywords = map +($_, 1), qw{ BEGIN INIT CHECK END DESTROY AUTOLOAD };
13 | 1 | 2µs |  |  | $keywords{UNITCHECK}++ if $] > 5.009;
14 |  |  |  |  |
15 | 1 | 7µs |  |  | my %forced_into_main = map +($_, 1),
16 |  |  |  |  | qw{ STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG };
17 |  |  |  |  |
18 | 1 | 7µs |  |  | my %forbidden = (%keywords, %forced_into_main);
19 |  |  |  |  |
20 | 1 | 11µs | 1 | 3µs | my $normal_constant_name = qr/^_?[^\W_0-9]\w*\z/; # spent 3µs making 1 call to constant::CORE:qr
21 | 1 | 4µs | 1 | 1µs | my $tolerable = qr/^[A-Za-z_]\w*\z/; # spent 1µs making 1 call to constant::CORE:qr
22 | 1 | 3µs | 1 | 700ns | my $boolean = qr/^[01]?\z/; # spent 700ns making 1 call to constant::CORE:qr
23 |  |  |  |  |
24 |  |  |  |  | # spent 24µs (22+2) within constant::BEGIN@24 which was called: # once (22µs+2µs) by Try::Tiny::ScopeGuard::BEGIN@161 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 | 2µs |  |  | my $const = $] > 5.009002;
30 | 1 | 700ns |  |  | my $downgrade = $] < 5.015004; # && $] >= 5.008
31 | 1 | 700ns |  |  | my $constarray = exists &_make_const;
32 | 1 | 4µs |  |  | if ($const) {
33 | 1 | 9µs | 1 | 2µs | Internals::SvREADONLY($const, 1); # spent 2µs making 1 call to Internals::SvREADONLY
34 | 1 | 4µs | 1 | 800ns | Internals::SvREADONLY($downgrade, 1); # spent 800ns making 1 call to Internals::SvREADONLY
35 | 1 | 2µs |  |  | $constant::{_CAN_PCS} = \$const;
36 | 1 | 300ns |  |  | $constant::{_DOWNGRADE} = \$downgrade;
37 | 1 | 800ns |  |  | $constant::{_CAN_PCS_FOR_ARRAY} = \$constarray;
38 |  |  |  |  | }
39 |  |  |  |  | else {
40 | 2 | 139µs | 2 | 45µs | # spent 28µs (11+17) within constant::BEGIN@40 which was called: # once (11µs+17µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 40 no strict 'refs'; # spent 28µs making 1 call to constant::BEGIN@40 # spent 17µ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 | 99µs | 1 | 24µs | } # spent 24µ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 996µs (775+221) within constant::import which was called 22 times, avg 45µs/call: # once (55µs+14µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 161 of Try/Tiny.pm # once (50µs+13µs) by File::Spec::Unix::BEGIN@130 at line 130 of File/Spec/Unix.pm # once (44µs+18µs) by DateTime::TimeZone::BEGIN@27 at line 27 of DateTime/TimeZone.pm # once (42µs+14µs) by DateTime::TimeZone::BEGIN@18 at line 18 of DateTime/TimeZone.pm # once (42µs+13µs) by DateTime::Duration::BEGIN@22 at line 22 of DateTime/Duration.pm # once (37µs+12µs) by DateTime::BEGIN@72 at line 72 of DateTime.pm # once (38µs+10µs) by DateTime::TimeZone::BEGIN@28 at line 28 of DateTime/TimeZone.pm # once (36µs+10µs) by DateTime::TimeZone::BEGIN@22 at line 22 of DateTime/TimeZone.pm # once (34µs+11µs) by DateTime::TimeZone::BEGIN@19 at line 19 of DateTime/TimeZone.pm # once (33µs+10µs) by File::Spec::Unix::BEGIN@223 at line 223 of File/Spec/Unix.pm # once (32µs+9µs) by DateTime::TimeZone::BEGIN@23 at line 23 of DateTime/TimeZone.pm # once (32µs+9µs) by DateTime::TimeZone::BEGIN@24 at line 24 of DateTime/TimeZone.pm # once (32µs+9µs) by File::Spec::Unix::BEGIN@245 at line 245 of File/Spec/Unix.pm # once (33µs+8µs) by DateTime::BEGIN@74 at line 74 of DateTime.pm # once (32µs+9µs) by DateTime::TimeZone::BEGIN@26 at line 26 of DateTime/TimeZone.pm # once (31µs+8µs) by File::Spec::Unix::BEGIN@139 at line 139 of File/Spec/Unix.pm # once (30µs+8µs) by DateTime::TimeZone::BEGIN@25 at line 25 of DateTime/TimeZone.pm # once (30µs+8µs) by File::Spec::Unix::BEGIN@148 at line 148 of File/Spec/Unix.pm # once (29µs+7µs) by DateTime::BEGIN@75 at line 75 of DateTime.pm # once (28µs+7µs) by DateTime::BEGIN@80 at line 80 of DateTime.pm # once (28µs+7µs) by DateTime::BEGIN@78 at line 78 of DateTime.pm # once (28µs+6µs) by DateTime::BEGIN@76 at line 76 of DateTime.pm sub import {
56 | 22 | 10µs |  |  | my $class = shift;
57 | 22 | 10µs |  |  | return unless @_; # Ignore 'use constant;'
58 | 22 | 3µs |  |  | my $constants;
59 | 22 | 11µs |  |  | my $multiple = ref $_[0];
60 | 22 | 12µs |  |  | my $caller = caller;
61 | 22 | 5µs |  |  | my $flush_mro;
62 |  |  |  |  | my $symtab;
63 |  |  |  |  |
64 | 22 | 9µs |  |  | if (_CAN_PCS) {
65 | 2 | 200µs | 2 | 38µs | # spent 24µs (10+14) within constant::BEGIN@65 which was called: # once (10µs+14µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 65 no strict 'refs'; # spent 24µs making 1 call to constant::BEGIN@65 # spent 14µs making 1 call to strict::unimport
66 | 22 | 34µs |  |  | $symtab = \%{$caller . '::'};
67 |  |  |  |  | };
68 |  |  |  |  |
69 | 22 | 8µ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 | 22 | 7µs |  |  | unless (defined $_[0]) {
77 |  |  |  |  | require Carp;
78 |  |  |  |  | Carp::croak("Can't use undef as constant name");
79 |  |  |  |  | }
80 | 22 | 34µs |  |  | $constants->{+shift} = undef;
81 |  |  |  |  | }
82 |  |  |  |  |
83 | 22 | 40µs |  |  | foreach my $name ( keys %$constants ) {
84 | 22 | 4µs |  |  | my $pkg;
85 | 22 | 6µs |  |  | my $symtab = $symtab;
86 | 22 | 4µs |  |  | my $orig_name = $name;
87 | 22 | 153µs | 22 | 67µs | if ($name =~ s/(.*)(?:::|')(?=.)//s) { # spent 67µs making 22 calls to constant::CORE:subst, avg 3µs/call
88 |  |  |  |  | $pkg = $1;
89 |  |  |  |  | if (_CAN_PCS && $pkg ne $caller) {
90 | 2 | 273µs | 2 | 41µs | # spent 26µs (12+14) within constant::BEGIN@90 which was called: # once (12µs+14µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 90 no strict 'refs'; # spent 26µs making 1 call to constant::BEGIN@90 # spent 14µs making 1 call to strict::unimport
91 |  |  |  |  | $symtab = \%{$pkg . '::'};
92 |  |  |  |  | }
93 |  |  |  |  | }
94 |  |  |  |  | else {
95 | 22 | 8µs |  |  | $pkg = $caller;
96 |  |  |  |  | }
97 |  |  |  |  |
98 |  |  |  |  | # Normal constant name
99 | 22 | 202µs | 44 | 102µs | if ($name =~ $normal_constant_name and !$forbidden{$name}) { # spent 57µs making 22 calls to constant::CORE:match, avg 3µs/call # spent 45µs making 22 calls to constant::CORE:regcomp, avg 2µ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 | 24 | 529µs | 2 | 38µs | # spent 24µs (10+14) within constant::BEGIN@141 which was called: # once (10µs+14µs) by Try::Tiny::ScopeGuard::BEGIN@161 at line 141 no strict 'refs'; # spent 24µs making 1 call to constant::BEGIN@141 # spent 14µs making 1 call to strict::unimport
142 | 22 | 21µs |  |  | my $full_name = "${pkg}::$name";
143 | 22 | 27µs |  |  | $declared{$full_name}++;
144 | 22 | 19µs |  |  | if ($multiple || @_ == 1) {
145 | 22 | 9µ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 | 22 | 8µ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 | 22 | 78µs | 22 | 23µs | Internals::SvREADONLY($scalar, 1); # spent 23µs making 22 calls to Internals::SvREADONLY, avg 1µs/call
165 | 22 | 19µs |  |  | if (!exists $symtab->{$name}) {
166 | 19 | 13µs |  |  | $symtab->{$name} = \$scalar;
167 | 19 | 20µs |  |  | ++$flush_mro->{$pkg};
168 |  |  |  |  | }
169 |  |  |  |  | else {
170 | 3 | 3µs |  |  | local $constant::{_dummy} = \$scalar;
171 | 3 | 16µs |  |  | *$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 | 22 | 122µs |  |  | if (_CAN_PCS && $flush_mro) {
198 | 19 | 117µs | 19 | 29µs | mro::method_changed_in($_) for keys %$flush_mro; # spent 29µs making 19 calls to mro::method_changed_in, avg 2µs/call
199 |  |  |  |  | }
200 |  |  |  |  | }
201 |  |  |  |  |
202 | 1 | 11µs |  |  | 1;
203 |  |  |  |  |
204 |  |  |  |  | __END__
|  |  |  |  | # spent 57µs within constant::CORE:match which was called 22 times, avg 3µs/call: # 22 times (57µs+0s) by constant::import at line 99, avg 3µs/call sub constant::CORE:match; # opcode
|  |  |  |  | # spent 4µs within constant::CORE:qr which was called 3 times, avg 1µs/call: # once (3µs+0s) by Try::Tiny::ScopeGuard::BEGIN@161 at line 20 # once (1µs+0s) by Try::Tiny::ScopeGuard::BEGIN@161 at line 21 # once (700ns+0s) by Try::Tiny::ScopeGuard::BEGIN@161 at line 22 sub constant::CORE:qr; # opcode
|  |  |  |  | # spent 45µs within constant::CORE:regcomp which was called 22 times, avg 2µs/call: # 22 times (45µs+0s) by constant::import at line 99, avg 2µs/call sub constant::CORE:regcomp; # opcode
|  |  |  |  | # spent 67µs within constant::CORE:subst which was called 22 times, avg 3µs/call: # 22 times (67µs+0s) by constant::import at line 87, avg 3µs/call sub constant::CORE:subst; # opcode