← Index
NYTProf Performance Profile   « block view • line view • sub view »
For -e
  Run on Wed Nov 17 21:45:08 2010
Reported on Wed Nov 17 22:10:28 2010

Filename/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Try/Tiny.pm
StatementsExecuted 10636 statements in 58.6ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
4864445.6ms7.23sTry::Tiny::::try Try::Tiny::try (recurses: max depth 4, inclusive time 2.01s)
480339.99ms9.99msTry::Tiny::::catch Try::Tiny::catch
11169µs87µsTry::Tiny::::BEGIN@3 Try::Tiny::BEGIN@3
11143µs43µsTry::Tiny::::BEGIN@8 Try::Tiny::BEGIN@8
11142µs254µsTry::Tiny::::BEGIN@46 Try::Tiny::BEGIN@46
11138µs354µsTry::Tiny::::BEGIN@6 Try::Tiny::BEGIN@6
0000s0sTry::Tiny::ScopeGuard::::DESTROYTry::Tiny::ScopeGuard::DESTROY
0000s0sTry::Tiny::ScopeGuard::::_newTry::Tiny::ScopeGuard::_new
0000s0sTry::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
1package Try::Tiny;
2
33115µs2105µs
# spent 87µs (69+18) within Try::Tiny::BEGIN@3 which was called: # once (69µs+18µs) by Class::MOP::BEGIN@14 at line 3
use strict;
# spent 87µs making 1 call to Try::Tiny::BEGIN@3 # spent 18µs making 1 call to strict::import
4#use warnings;
5
63155µs2669µs
# spent 354µs (38+316) within Try::Tiny::BEGIN@6 which was called: # once (38µs+316µs) by Class::MOP::BEGIN@14 at line 6
use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA);
# spent 354µs making 1 call to Try::Tiny::BEGIN@6 # spent 316µs making 1 call to vars::import
7
8
# spent 43µs within Try::Tiny::BEGIN@8 which was called: # once (43µs+0s) by Class::MOP::BEGIN@14 at line 11
BEGIN {
9242µs require Exporter;
10 @ISA = qw(Exporter);
111447µs143µs}
# spent 43µs making 1 call to Try::Tiny::BEGIN@8
12
1314µs$VERSION = "0.07";
14
15167µs$VERSION = eval $VERSION;
# spent 10µs executing statements in string eval
16
17110µs@EXPORT = @EXPORT_OK = qw(try catch finally);
18
1914µs$Carp::Internal{+__PACKAGE__}++;
20
21# Need to prototype as @ not $$ because of the way Perl evaluates the prototype.
22# Keeping it at $$ means you only ever get 1 sub because we need to eval in a list
23# context & not a scalar one
24
25
# spent 7.23s (45.6ms+7.18) within Try::Tiny::try which was called 486 times, avg 14.9ms/call: # 256 times (24.2ms+-24.2ms) by Class::MOP::Attribute::_process_accessors at line 345 of Class/MOP/Attribute.pm, avg 0s/call # 187 times (17.3ms+1.37s) by Class::MOP::Class::_post_add_attribute at line 794 of Class/MOP/Class.pm, avg 7.42ms/call # 37 times (3.61ms+5.83s) by Class::MOP::load_first_existing_class at line 125 of Class/MOP.pm, avg 158ms/call # 6 times (463µs+5.47ms) by Moose::Meta::Attribute::does at line 40 of Moose/Meta/Attribute.pm, avg 989µs/call
sub try (&;@) {
26437415.5ms my ( $try, @code_refs ) = @_;
27
28 # we need to save this here, the eval block will be in scalar context due
29 # to $failed
30 my $wantarray = wantarray;
31
32 my ( $catch, @finally );
33
34 # find labeled blocks in the argument list.
35 # catch and finally tag the blocks by blessing a scalar reference to them.
36 foreach my $code_ref (@code_refs) {
3714406.47ms next unless $code_ref;
38
39 my $ref = ref($code_ref);
40
41 if ( $ref eq 'Try::Tiny::Catch' ) {
42 $catch = ${$code_ref};
43 } elsif ( $ref eq 'Try::Tiny::Finally' ) {
44 push @finally, ${$code_ref};
45 } else {
4631.10ms2466µs
# spent 254µs (42+212) within Try::Tiny::BEGIN@46 which was called: # once (42µs+212µs) by Class::MOP::BEGIN@14 at line 46
use Carp;
# spent 254µs making 1 call to Try::Tiny::BEGIN@46 # spent 212µs making 1 call to Exporter::import
47 confess("Unknown code ref type given '${ref}'. Check your usage & try again");
48 }
49 }
50
51 # save the value of $@ so we can set $@ back to it in the beginning of the eval
52 my $prev_error = $@;
53
54 my ( @ret, $error, $failed );
55
56 # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's
57 # not perfect, but we could provide a list of additional errors for
58 # $catch->();
59
60 {
61 # localize $@ to prevent clobbering of previous value by a successful
62 # eval.
6314586.30ms local $@;
64
65 # failed will be true if the eval dies, because 1 will not be returned
66 # from the eval body
6714535.50ms $failed = not eval {
68 $@ = $prev_error;
69
70 # evaluate the try block in the correct context
714434.60ms437.21s if ( $wantarray ) {
# spent 7.20s making 37 calls to Class::MOP::__ANON__[Class/MOP.pm:118], avg 195ms/call # spent 5.47ms making 6 calls to Moose::Meta::Attribute::__ANON__[Moose/Meta/Attribute.pm:40], avg 911µs/call
72 @ret = $try->();
73 } elsif ( defined $wantarray ) {
74 $ret[0] = $try->();
75 } else {
764431.98s $try->();
# spent 1.56s making 187 calls to Class::MOP::Class::__ANON__[Class/MOP/Class.pm:790], avg 8.33ms/call # spent 422ms making 256 calls to Class::MOP::Attribute::__ANON__[Class/MOP/Attribute.pm:342], avg 1.65ms/call
77 };
78
79 return 1; # properly set $fail to false
80 };
81
82 # copy $@ to $error; when we leave this scope, local $@ will revert $@
83 # back to its previous value
84 $error = $@;
85 }
86
87 # set up a scope guard to invoke the finally block at the end
88 my @guards =
89 map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) }
90 @finally;
91
92 # at this point $failed contains a true value if the eval died, even if some
93 # destructor overwrote $@ as the eval was unwinding.
944866.66ms if ( $failed ) {
95 # if we got an error, invoke the catch block.
96 if ( $catch ) {
97 # This works like given($error), but is backwards compatible and
98 # sets $_ in the dynamic scope for the body of C<$catch>
99 for ($error) {
1005116µs5478µs return $catch->($error);
# spent 478µs making 5 calls to Class::MOP::__ANON__[Class/MOP.pm:125], avg 96µs/call
101 }
102
103 # in case when() was used without an explicit return, the C<for>
104 # loop will be aborted and there's no useful return value
105 }
106
107 return;
108 } else {
109 # no failure, $@ is back to what it was, everything is fine
110 return $wantarray ? @ret : $ret[0];
111 }
112}
113
114
# spent 9.99ms within Try::Tiny::catch which was called 480 times, avg 21µs/call: # 256 times (5.09ms+0s) by Class::MOP::Attribute::_process_accessors at line 345 of Class/MOP/Attribute.pm, avg 20µs/call # 187 times (4.11ms+0s) by Class::MOP::Class::_post_add_attribute at line 794 of Class/MOP/Class.pm, avg 22µs/call # 37 times (800µs+0s) by Class::MOP::load_first_existing_class at line 125 of Class/MOP.pm, avg 22µs/call
sub catch (&;@) {
11596011.5ms my ( $block, @rest ) = @_;
116
117 return (
118 bless(\$block, 'Try::Tiny::Catch'),
119 @rest,
120 );
121}
122
123sub finally (&;@) {
124 my ( $block, @rest ) = @_;
125
126 return (
127 bless(\$block, 'Try::Tiny::Finally'),
128 @rest,
129 );
130}
131
132{
13315µs package Try::Tiny::ScopeGuard;
134
135 sub _new {
136 shift;
137 bless [ @_ ];
138 }
139
140 sub DESTROY {
141 my @guts = @{ shift() };
142 my $code = shift @guts;
143 $code->(@guts);
144 }
145}
146
147__PACKAGE__
148
149118µs__END__