← Index
NYTProf Performance Profile   « line view »
For fastest.pl
  Run on Fri Jan 31 20:48:16 2014
Reported on Fri Jan 31 20:49:41 2014

Filename/opt/perl-5.18.1/lib/site_perl/5.18.1/Sub/Defer.pm
StatementsExecuted 124 statements in 892µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
922108µs188µsSub::Defer::::defer_subSub::Defer::defer_sub
31167µs2.65msSub::Defer::::undefer_subSub::Defer::undefer_sub
11124µs86µsSub::Defer::::BEGIN@3Sub::Defer::BEGIN@3
11111µs23µsSub::Defer::::BEGIN@26Sub::Defer::BEGIN@26
11111µs79µsSub::Defer::::BEGIN@5Sub::Defer::BEGIN@5
1119µs83µsSub::Defer::::BEGIN@4Sub::Defer::BEGIN@4
1118µs36µsSub::Defer::::BEGIN@6Sub::Defer::BEGIN@6
3118µs8µsSub::Defer::::defer_infoSub::Defer::defer_info
0000s0sSub::Defer::::CLONESub::Defer::CLONE
0000s0sSub::Defer::::__ANON__[:49]Sub::Defer::__ANON__[:49]
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Sub::Defer;
2
3342µs3147µs
# spent 86µs (24+61) within Sub::Defer::BEGIN@3 which was called: # once (24µs+61µs) by Moo::BEGIN@6 at line 3
use strictures 1;
# spent 86µs making 1 call to Sub::Defer::BEGIN@3 # spent 40µs making 1 call to strictures::import # spent 21µs making 1 call to strictures::VERSION
4243µs2156µs
# spent 83µs (9+73) within Sub::Defer::BEGIN@4 which was called: # once (9µs+73µs) by Moo::BEGIN@6 at line 4
use base qw(Exporter);
# spent 83µs making 1 call to Sub::Defer::BEGIN@4 # spent 73µs making 1 call to base::import
5236µs2148µs
# spent 79µs (11+68) within Sub::Defer::BEGIN@5 which was called: # once (11µs+68µs) by Moo::BEGIN@6 at line 5
use Moo::_Utils;
# spent 79µs making 1 call to Sub::Defer::BEGIN@5 # spent 68µs making 1 call to Exporter::import
62163µs263µs
# spent 36µs (8+27) within Sub::Defer::BEGIN@6 which was called: # once (8µs+27µs) by Moo::BEGIN@6 at line 6
use Scalar::Util qw(weaken);
# spent 36µs making 1 call to Sub::Defer::BEGIN@6 # spent 27µs making 1 call to Exporter::import
7
81900nsour $VERSION = '1.003001';
9115µs$VERSION = eval $VERSION;
# spent 3µs executing statements in string eval
10
1111µsour @EXPORT = qw(defer_sub undefer_sub);
12
131100nsour %DEFERRED;
14
15
# spent 2.65ms (67µs+2.58) within Sub::Defer::undefer_sub which was called 3 times, avg 883µs/call: # 3 times (67µs+2.58ms) by Foo::Moo::QS::new or Foo::Moo::new or Method::Generate::Constructor::new at line 47, avg 883µs/call
sub undefer_sub {
163800ns my ($deferred) = @_;
17 my ($target, $maker, $undeferred_ref) = @{
1834µs $DEFERRED{$deferred}||return $deferred
19 };
20 return ${$undeferred_ref}
213700ns if ${$undeferred_ref};
2236µs32.57ms ${$undeferred_ref} = my $made = $maker->();
# spent 2.57ms making 3 calls to Method::Generate::Constructor::__ANON__[Method/Generate/Constructor.pm:64], avg 855µs/call
23
24 # make sure the method slot has not changed since deferral time
25314µs38µs if (defined($target) && $deferred eq *{_getglob($target)}{CODE}||'') {
# spent 8µs making 3 calls to Moo::_Utils::_getglob, avg 3µs/call
262369µs234µs
# spent 23µs (11+11) within Sub::Defer::BEGIN@26 which was called: # once (11µs+11µs) by Moo::BEGIN@6 at line 26
no warnings 'redefine';
# spent 23µs making 1 call to Sub::Defer::BEGIN@26 # spent 11µs making 1 call to warnings::unimport
27
28 # I believe $maker already evals with the right package/name, so that
29 # _install_coderef calls are not necessary --ribasushi
3036µs34µs *{_getglob($target)} = $made;
# spent 4µs making 3 calls to Moo::_Utils::_getglob, avg 1µs/call
31 }
32316µs34µs weaken($DEFERRED{$made} = $DEFERRED{$deferred});
# spent 4µs making 3 calls to Scalar::Util::weaken, avg 1µs/call
33
34314µs return $made;
35}
36
37
# spent 8µs within Sub::Defer::defer_info which was called 3 times, avg 3µs/call: # 3 times (8µs+0s) by Moo::_accessor_maker_for at line 124 of Moo.pm, avg 3µs/call
sub defer_info {
383900ns my ($deferred) = @_;
39311µs $DEFERRED{$deferred||''};
40}
41
42
# spent 188µs (108+80) within Sub::Defer::defer_sub which was called 9 times, avg 21µs/call: # 6 times (67µs+35µs) by Sub::Quote::quote_sub at line 69 of Sub/Quote.pm, avg 17µs/call # 3 times (42µs+45µs) by Method::Generate::Constructor::install_delayed at line 64 of Method/Generate/Constructor.pm, avg 29µs/call
sub defer_sub {
4394µs my ($target, $maker) = @_;
449900ns my $undeferred;
459200ns my $deferred_info;
46 my $deferred = sub {
4739µs32.65ms $undeferred ||= undefer_sub($deferred_info->[3]);
# spent 2.65ms making 3 calls to Sub::Defer::undefer_sub, avg 883µs/call
48317µs328µs goto &$undeferred;
# spent 15µs making 1 call to Method::Generate::Constructor::new # spent 6µs making 1 call to Foo::Moo::new # spent 6µs making 1 call to Foo::Moo::QS::new
49918µs };
5099µs $deferred_info = [ $target, $maker, \$undeferred, $deferred ];
51951µs910µs weaken($DEFERRED{$deferred} = $deferred_info);
# spent 10µs making 9 calls to Scalar::Util::weaken, avg 1µs/call
5298µs570µs _install_coderef($target => $deferred) if defined $target;
# spent 70µs making 5 calls to Moo::_Utils::_install_coderef, avg 14µs/call
53927µs return $deferred;
54}
55
56sub CLONE {
57 %DEFERRED = map { defined $_ ? ($_->[3] => $_) : () } values %DEFERRED;
58 weaken($_) for values %DEFERRED;
59}
60
6115µs1;
62
63=head1 NAME
64
65Sub::Defer - defer generation of subroutines until they are first called
66
67=head1 SYNOPSIS
68
69 use Sub::Defer;
70
71 my $deferred = defer_sub 'Logger::time_since_first_log' => sub {
72 my $t = time;
73 sub { time - $t };
74 };
75
76 Logger->time_since_first_log; # returns 0 and replaces itself
77 Logger->time_since_first_log; # returns time - $t
78
79=head1 DESCRIPTION
80
81These subroutines provide the user with a convenient way to defer creation of
82subroutines and methods until they are first called.
83
84=head1 SUBROUTINES
85
86=head2 defer_sub
87
88 my $coderef = defer_sub $name => sub { ... };
89
90This subroutine returns a coderef that encapsulates the provided sub - when
91it is first called, the provided sub is called and is -itself- expected to
92return a subroutine which will be goto'ed to on subsequent calls.
93
94If a name is provided, this also installs the sub as that name - and when
95the subroutine is undeferred will re-install the final version for speed.
96
97=head2 undefer_sub
98
99 my $coderef = undefer_sub \&Foo::name;
100
101If the passed coderef has been L<deferred|/defer_sub> this will "undefer" it.
102If the passed coderef has not been deferred, this will just return it.
103
104If this is confusing, take a look at the example in the L</SYNOPSIS>.
105
106=head1 SUPPORT
107
108See L<Moo> for support and contact information.
109
110=head1 AUTHORS
111
112See L<Moo> for authors.
113
114=head1 COPYRIGHT AND LICENSE
115
116See L<Moo> for the copyright and license.