Profile of Try/Tiny.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:09 2016

Filename | /usr/share/perl5/Try/Tiny.pm
Statements | Executed 25916626 statements in 29.6s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1332073 | 18 | 13 | 24.6s | 903s | Try::Tiny::::try Try::Tiny::try (recurses: max depth 3, inclusive time 30.9s)
101107 | 14 | 10 | 1.06s | 1.06s | Try::Tiny::::catch Try::Tiny::catch
1 | 1 | 1 | 816µs | 1.13ms | Try::Tiny::ScopeGuard::::BEGIN@144Try::Tiny::ScopeGuard::BEGIN@144
1 | 1 | 1 | 30µs | 540µs | Try::Tiny::::BEGIN@18 Try::Tiny::BEGIN@18
1 | 1 | 1 | 11µs | 26µs | Try::Tiny::::BEGIN@12 Try::Tiny::BEGIN@12
1 | 1 | 1 | 8µs | 8µs | Try::Tiny::::BEGIN@6 Try::Tiny::BEGIN@6
1 | 1 | 1 | 6µs | 9µs | Try::Tiny::::BEGIN@10 Try::Tiny::BEGIN@10
1 | 1 | 1 | 6µs | 6µs | Try::Tiny::::BEGIN@2 Try::Tiny::BEGIN@2
1 | 1 | 1 | 5µs | 38µs | Try::Tiny::::BEGIN@15 Try::Tiny::BEGIN@15
1 | 1 | 1 | 5µs | 14µs | Try::Tiny::::BEGIN@9 Try::Tiny::BEGIN@9
0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::::DESTROYTry::Tiny::ScopeGuard::DESTROY
0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::::_newTry::Tiny::ScopeGuard::_new
0 | 0 | 0 | 0s | 0s | Try::Tiny::::__ANON__[:18] Try::Tiny::__ANON__[:18]
0 | 0 | 0 | 0s | 0s | Try::Tiny::::finally Try::Tiny::finally

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Try::Tiny;
2 |  |  |  |  | # spent 6µs within Try::Tiny::BEGIN@2 which was called: # once (6µs+0s) by Module::Implementation::BEGIN@13 at line 4 BEGIN {
3 | 1 | 4µs |  |  | $Try::Tiny::AUTHORITY = 'cpan:NUFFIN';
4 | 1 | 20µs | 1 | 6µs | } # spent 6µs making 1 call to Try::Tiny::BEGIN@2
5 | 1 | 400ns |  |  | $Try::Tiny::VERSION = '0.19';
6 | 2 | 34µs | 1 | 8µs | # spent 8µs within Try::Tiny::BEGIN@6 which was called: # once (8µs+0s) by Module::Implementation::BEGIN@13 at line 6 use 5.006; # spent 8µs making 1 call to Try::Tiny::BEGIN@6
7 |  |  |  |  | # ABSTRACT: minimal try/catch with proper preservation of $@
8 |  |  |  |  |
9 | 2 | 18µs | 2 | 23µs | # spent 14µs (5+9) within Try::Tiny::BEGIN@9 which was called: # once (5µs+9µs) by Module::Implementation::BEGIN@13 at line 9 use strict; # spent 14µs making 1 call to Try::Tiny::BEGIN@9 # spent 9µs making 1 call to strict::import
10 | 2 | 21µs | 2 | 12µs | # spent 9µs (6+3) within Try::Tiny::BEGIN@10 which was called: # once (6µs+3µs) by Module::Implementation::BEGIN@13 at line 10 use warnings; # spent 9µs making 1 call to Try::Tiny::BEGIN@10 # spent 3µs making 1 call to warnings::import
11 |  |  |  |  |
12 | 3 | 46µs | 3 | 40µs | # spent 26µs (11+15) within Try::Tiny::BEGIN@12 which was called: # once (11µs+15µs) by Module::Implementation::BEGIN@13 at line 12 use Exporter 5.57 'import'; # spent 26µs making 1 call to Try::Tiny::BEGIN@12 # spent 8µs making 1 call to UNIVERSAL::VERSION # spent 6µs making 1 call to Exporter::import
13 | 1 | 1µs |  |  | our @EXPORT = our @EXPORT_OK = qw(try catch finally);
14 |  |  |  |  |
15 | 2 | 39µs | 2 | 71µs | # spent 38µs (5+33) within Try::Tiny::BEGIN@15 which was called: # once (5µs+33µs) by Module::Implementation::BEGIN@13 at line 15 use Carp; # spent 38µs making 1 call to Try::Tiny::BEGIN@15 # spent 33µs making 1 call to Exporter::import
16 | 1 | 700ns |  |  | $Carp::Internal{+__PACKAGE__}++;
17 |  |  |  |  |
18 | 1 | 347µs | 1 | 540µs | # spent 540µs (30+510) within Try::Tiny::BEGIN@18 which was called: # once (30µs+510µs) by Module::Implementation::BEGIN@13 at line 18 BEGIN { eval "use Sub::Name; 1" or *{subname} = sub {1} } # spent 540µs making 1 call to Try::Tiny::BEGIN@18 # spent 82µs executing statements in string eval # includes 206µs spent executing 1 call to 1 sub defined therein.
19 |  |  |  |  |
20 |  |  |  |  | # Need to prototype as @ not $$ because of the way Perl evaluates the prototype.
21 |  |  |  |  | # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list
22 |  |  |  |  | # context & not a scalar one
23 |  |  |  |  |
24 |  |  |  |  | # spent 903s (24.6+878) within Try::Tiny::try which was called 1332073 times, avg 678µs/call: # 1230932 times (20.3s+-20.3s) by Moose::Util::does_role at line 69 of Moose/Util.pm, avg 0ns/call # 100001 times (4.34s+898s) by Plack::Middleware::StackTrace::call at line 42 of Plack/Middleware/StackTrace.pm, avg 9.02ms/call # 333 times (3.89ms+34.6ms) by Class::MOP::Attribute::_process_accessors at line 423 of Class/MOP/Attribute.pm, avg 116µs/call # 240 times (3.22ms+526ms) by Class::MOP::Class::_post_add_attribute at line 904 of Class/MOP/Class.pm, avg 2.20ms/call # 196 times (7.21ms+-7.21ms) by Moose::Meta::Method::Accessor::_compile_code at line 41 of Moose/Meta/Method/Accessor.pm, avg 0s/call # 165 times (6.32ms+-6.32ms) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 169 of Class/MOP/Method/Accessor.pm, avg 0s/call # 58 times (955µs+78.4ms) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 115 of Class/MOP/Method/Constructor.pm, avg 1.37ms/call # 45 times (614µs+-614µs) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 230 of Class/MOP/Method/Accessor.pm, avg 0s/call # 32 times (402µs+717µs) by Moose::Meta::Attribute::does at line 39 of Moose/Meta/Attribute.pm, avg 35µs/call # 28 times (438µs+14.0ms) by Moose::Meta::Method::Destructor::_initialize_body at line 100 of Moose/Meta/Method/Destructor.pm, avg 514µs/call # 21 times (281µs+-281µs) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 127 of Class/MOP/Method/Accessor.pm, avg 0s/call # 8 times (108µs+-108µs) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 202 of Class/MOP/Method/Accessor.pm, avg 0s/call # 7 times (153µs+49.5ms) by Class::Load::try_load_class at line 185 of Class/Load.pm, avg 7.10ms/call # 3 times (61µs+3.34ms) by Module::Implementation::_load_implementation at line 93 of Module/Implementation.pm, avg 1.13ms/call # once (22µs+24.7ms) by Plack::Loader::auto at line 31 of Plack/Loader.pm # once (26µs+47µs) by Plack::Util::load_class at line 14 of Plack/Middleware/StackTrace.pm # once (20µs+-20µs) by Plack::Loader::load at line 44 of Plack/Loader.pm # once (17µs+-17µs) by HTTP::Server::PSGI::BEGIN@7 at line 10 of Plack/HTTPParser.pm sub try (&;@) {
25 | 1332073 | 661ms |  |  | my ( $try, @code_refs ) = @_;
26 |  |  |  |  |
27 |  |  |  |  | # we need to save this here, the eval block will be in scalar context due
28 |  |  |  |  | # to $failed
29 | 1332073 | 651ms |  |  | my $wantarray = wantarray;
30 |  |  |  |  |
31 |  |  |  |  | # work around perl bug by explicitly initializing these, due to the likelyhood
32 |  |  |  |  | # this will be used in global destruction (perl rt#119311)
33 | 1332073 | 474ms |  |  | my ( $catch, @finally ) = ();
34 |  |  |  |  |
35 |  |  |  |  | # find labeled blocks in the argument list.
36 |  |  |  |  | # catch and finally tag the blocks by blessing a scalar reference to them.
37 | 1332073 | 1.13s |  |  | foreach my $code_ref (@code_refs) {
38 |  |  |  |  |
39 | 101107 | 361ms |  |  | if ( ref($code_ref) eq 'Try::Tiny::Catch' ) {
40 | 101107 | 46.6ms |  |  | croak 'A try() may not be followed by multiple catch() blocks'
41 |  |  |  |  | if $catch;
42 | 101107 | 89.8ms |  |  | $catch = ${$code_ref};
43 |  |  |  |  | } elsif ( ref($code_ref) eq 'Try::Tiny::Finally' ) {
44 |  |  |  |  | push @finally, ${$code_ref};
45 |  |  |  |  | } else {
46 |  |  |  |  | croak(
47 |  |  |  |  | 'try() encountered an unexpected argument ('
48 |  |  |  |  | . ( defined $code_ref ? $code_ref : 'undef' )
49 |  |  |  |  | . ') - perhaps a missing semi-colon before or'
50 |  |  |  |  | );
51 |  |  |  |  | }
52 |  |  |  |  | }
53 |  |  |  |  |
54 |  |  |  |  | # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's
55 |  |  |  |  | # not perfect, but we could provide a list of additional errors for
56 |  |  |  |  | # $catch->();
57 |  |  |  |  |
58 |  |  |  |  | # name the blocks if we have Sub::Name installed
59 | 1332073 | 1.05s |  |  | my $caller = caller;
60 | 1332073 | 10.1s | 1332073 | 4.58s | subname("${caller}::try {...} " => $try); # spent 4.58s making 1332073 calls to Sub::Name::subname, avg 3µs/call
61 | 1332073 | 1.14s | 101107 | 295ms | subname("${caller}::catch {...} " => $catch) if $catch; # spent 295ms making 101107 calls to Sub::Name::subname, avg 3µs/call
62 | 1332073 | 967ms |  |  | subname("${caller}::finally {...} " => $_) foreach @finally;
63 |  |  |  |  |
64 |  |  |  |  | # save the value of $@ so we can set $@ back to it in the beginning of the eval
65 |  |  |  |  | # and restore $@ after the eval finishes
66 | 1332073 | 465ms |  |  | my $prev_error = $@;
67 |  |  |  |  |
68 | 1332073 | 189ms |  |  | my ( @ret, $error );
69 |  |  |  |  |
70 |  |  |  |  | # failed will be true if the eval dies, because 1 will not be returned
71 |  |  |  |  | # from the eval body
72 | 1332073 | 979ms |  |  | my $failed = not eval {
73 | 1332073 | 357ms |  |  | $@ = $prev_error;
74 |  |  |  |  |
75 |  |  |  |  | # evaluate the try block in the correct context
76 | 1332073 | 2.00s | 1331496 | 903s | if ( $wantarray ) { # spent 896s making 100002 calls to Plack::Middleware::StackTrace::try {...} , avg 8.96ms/call # spent 6.51s making 1230932 calls to Moose::Util::try {...} , avg 5µs/call # spent 129ms making 239 calls to Class::MOP::Method::Accessor::try {...} , avg 541µs/call # spent 90.5ms making 196 calls to Moose::Meta::Method::Accessor::try {...} , avg 462µs/call # spent 78.1ms making 58 calls to Class::MOP::Method::Constructor::try {...} , avg 1.35ms/call # spent 49.5ms making 7 calls to Class::Load::try {...} , avg 7.07ms/call # spent 24.7ms making 1 call to Plack::Loader::try {...} # spent 13.9ms making 28 calls to Moose::Meta::Method::Destructor::try {...} , avg 495µs/call # spent 647µs making 32 calls to Moose::Meta::Attribute::try {...} , avg 20µs/call # spent 615µs making 1 call to Plack::HTTPParser::try {...}
77 |  |  |  |  | @ret = $try->();
78 |  |  |  |  | } elsif ( defined $wantarray ) {
79 |  |  |  |  | $ret[0] = $try->();
80 |  |  |  |  | } else {
81 | 577 | 442µs | 577 | 767ms | $try->(); # spent 525ms making 240 calls to Class::MOP::Class::try {...} , avg 2.19ms/call # spent 214ms making 333 calls to Class::MOP::Attribute::try {...} , avg 642µs/call # spent 24.6ms making 1 call to Plack::Loader::try {...} # spent 3.32ms making 3 calls to Module::Implementation::try {...} , avg 1.11ms/call
82 |  |  |  |  | };
83 |  |  |  |  |
84 | 1332071 | 646ms |  |  | return 1; # properly set $fail to false
85 |  |  |  |  | };
86 |  |  |  |  |
87 |  |  |  |  | # preserve the current error and reset the original value of $@
88 | 1332073 | 344ms |  |  | $error = $@;
89 | 1332073 | 289ms |  |  | $@ = $prev_error;
90 |  |  |  |  |
91 |  |  |  |  | # set up a scope guard to invoke the finally block at the end
92 |  |  |  |  | my @guards =
93 | 1332073 | 873ms |  |  | map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) }
94 |  |  |  |  | @finally;
95 |  |  |  |  |
96 |  |  |  |  | # at this point $failed contains a true value if the eval died, even if some
97 |  |  |  |  | # destructor overwrote $@ as the eval was unwinding.
98 | 1332073 | 334ms |  |  | if ( $failed ) {
99 |  |  |  |  | # if we got an error, invoke the catch block.
100 | 2 | 500ns |  |  | if ( $catch ) {
101 |  |  |  |  | # This works like given($error), but is backwards compatible and
102 |  |  |  |  | # sets $_ in the dynamic scope for the body of C<$catch>
103 |  |  |  |  | for ($error) {
104 | 1 | 5µs | 1 | 16µs | return $catch->($error); # spent 16µs making 1 call to Class::Load::catch {...}
105 |  |  |  |  | }
106 |  |  |  |  |
107 |  |  |  |  | # in case when() was used without an explicit return, the C<for>
108 |  |  |  |  | # loop will be aborted and there's no useful return value
109 |  |  |  |  | }
110 |  |  |  |  |
111 | 1 | 4µs |  |  | return;
112 |  |  |  |  | } else {
113 |  |  |  |  | # no failure, $@ is back to what it was, everything is fine
114 | 1332071 | 5.21s |  |  | return $wantarray ? @ret : $ret[0];
115 |  |  |  |  | }
116 |  |  |  |  | }
117 |  |  |  |  |
118 |  |  |  |  | # spent 1.06s within Try::Tiny::catch which was called 101107 times, avg 11µs/call: # 100001 times (1.06s+0s) by Plack::Middleware::StackTrace::call at line 42 of Plack/Middleware/StackTrace.pm, avg 11µs/call # 333 times (721µs+0s) by Class::MOP::Attribute::_process_accessors at line 423 of Class/MOP/Attribute.pm, avg 2µs/call # 240 times (658µs+0s) by Class::MOP::Class::_post_add_attribute at line 904 of Class/MOP/Class.pm, avg 3µs/call # 196 times (448µs+0s) by Moose::Meta::Method::Accessor::_compile_code at line 41 of Moose/Meta/Method/Accessor.pm, avg 2µs/call # 165 times (332µs+0s) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 169 of Class/MOP/Method/Accessor.pm, avg 2µs/call # 58 times (200µs+0s) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 115 of Class/MOP/Method/Constructor.pm, avg 3µs/call # 45 times (86µs+0s) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 230 of Class/MOP/Method/Accessor.pm, avg 2µs/call # 28 times (97µs+0s) by Moose::Meta::Method::Destructor::_initialize_body at line 100 of Moose/Meta/Method/Destructor.pm, avg 3µs/call # 21 times (38µs+0s) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 127 of Class/MOP/Method/Accessor.pm, avg 2µs/call # 8 times (16µs+0s) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 202 of Class/MOP/Method/Accessor.pm, avg 2µs/call # 7 times (29µs+0s) by Class::Load::try_load_class at line 185 of Class/Load.pm, avg 4µs/call # 3 times (14µs+0s) by Module::Implementation::_load_implementation at line 93 of Module/Implementation.pm, avg 5µs/call # once (4µs+0s) by Plack::Loader::auto at line 31 of Plack/Loader.pm # once (2µs+0s) by Plack::Loader::load at line 44 of Plack/Loader.pm sub catch (&;@) {
119 | 101107 | 123ms |  |  | my ( $block, @rest ) = @_;
120 |  |  |  |  |
121 | 101107 | 57.3ms |  |  | croak 'Useless bare catch()' unless wantarray;
122 |  |  |  |  |
123 |  |  |  |  | return (
124 | 101107 | 1.07s |  |  | bless(\$block, 'Try::Tiny::Catch'),
125 |  |  |  |  | @rest,
126 |  |  |  |  | );
127 |  |  |  |  | }
128 |  |  |  |  |
129 |  |  |  |  | sub finally (&;@) {
130 |  |  |  |  | my ( $block, @rest ) = @_;
131 |  |  |  |  |
132 |  |  |  |  | croak 'Useless bare finally()' unless wantarray;
133 |  |  |  |  |
134 |  |  |  |  | return (
135 |  |  |  |  | bless(\$block, 'Try::Tiny::Finally'),
136 |  |  |  |  | @rest,
137 |  |  |  |  | );
138 |  |  |  |  | }
139 |  |  |  |  |
140 |  |  |  |  | {
141 | 1 | 400ns |  |  | package # hide from PAUSE
142 |  |  |  |  | Try::Tiny::ScopeGuard;
143 |  |  |  |  |
144 | 2 | 171µs | 2 | 1.26ms | # spent 1.13ms (816µs+318µs) within Try::Tiny::ScopeGuard::BEGIN@144 which was called: # once (816µs+318µs) by Module::Implementation::BEGIN@13 at line 144 use constant UNSTABLE_DOLLARAT => ($] < '5.013002') ? 1 : 0; # spent 1.13ms making 1 call to Try::Tiny::ScopeGuard::BEGIN@144 # spent 127µs making 1 call to constant::import
145 |  |  |  |  |
146 |  |  |  |  | sub _new {
147 |  |  |  |  | shift;
148 |  |  |  |  | bless [ @_ ];
149 |  |  |  |  | }
150 |  |  |  |  |
151 |  |  |  |  | sub DESTROY {
152 |  |  |  |  | my ($code, @args) = @{ $_[0] };
153 |  |  |  |  |
154 |  |  |  |  | local $@ if UNSTABLE_DOLLARAT;
155 |  |  |  |  | eval {
156 |  |  |  |  | $code->(@args);
157 |  |  |  |  | 1;
158 |  |  |  |  | } or do {
159 |  |  |  |  | warn
160 |  |  |  |  | "Execution of finally() block $code resulted in an exception, which "
161 |  |  |  |  | . '*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. '
162 |  |  |  |  | . 'Your program will continue as if this event never took place. '
163 |  |  |  |  | . "Original exception text follows:\n\n"
164 |  |  |  |  | . (defined $@ ? $@ : '$@ left undefined...')
165 |  |  |  |  | . "\n"
166 |  |  |  |  | ;
167 |  |  |  |  | }
168 |  |  |  |  | }
169 |  |  |  |  | }
170 |  |  |  |  |
171 |  |  |  |  | __PACKAGE__
172 |  |  |  |  |
173 | 1 | 3µs |  |  | __END__