File Coverage

blib/lib/Template/Timer.pm
Criterion Covered Total %
statement 31 46 67.3
branch 3 8 37.5
condition n/a
subroutine 7 7 100.0
pod n/a
total 41 61 67.2


line stmt bran cond sub pod time code
1             package Template::Timer;
2              
3 2     2   101987 use warnings;
  2         5  
  2         259  
4 2     2   12 use strict;
  2         4  
  2         116  
5              
6             =head1 NAME
7              
8             Template::Timer - Rudimentary profiling for Template Toolkit
9              
10             =head1 VERSION
11              
12             Version 1.00
13              
14             =cut
15              
16             our $VERSION = '1.00';
17              
18             =head1 SYNOPSIS
19              
20             Template::Timer provides inline timings of the template processing
21             througout your code. It's an overridden version of L<Template::Context>
22             that wraps the C<process()> and C<include()> methods.
23              
24             Using Template::Timer is simple.
25              
26             use Template::Timer;
27              
28             my %config = ( # Whatever your config is
29             INCLUDE_PATH => '/my/template/path',
30             COMPILE_EXT => '.ttc',
31             COMPILE_DIR => '/tmp/tt',
32             );
33              
34             if ( $development_mode ) {
35             $config{ CONTEXT } = Template::Timer->new( %config );
36             }
37              
38             my $template = Template->new( \%config );
39              
40             Now when you process templates, HTML comments will get embedded in your
41             output, which you can easily grep for. The nesting level is also shown.
42              
43             <!-- TIMER START: L1 process mainmenu/mainmenu.ttml -->
44             <!-- TIMER START: L2 include mainmenu/cssindex.tt -->
45             <!-- TIMER START: L3 process mainmenu/cssindex.tt -->
46             <!-- TIMER END: L3 process mainmenu/cssindex.tt (17.279 ms) -->
47             <!-- TIMER END: L2 include mainmenu/cssindex.tt (17.401 ms) -->
48              
49             ....
50              
51             <!-- TIMER END: L3 process mainmenu/footer.tt (3.016 ms) -->
52             <!-- TIMER END: L2 include mainmenu/footer.tt (3.104 ms) -->
53             <!-- TIMER END: L1 process mainmenu/mainmenu.ttml (400.409 ms) -->
54              
55             Note that since INCLUDE is a wrapper around PROCESS, calls to INCLUDEs
56             will be doubled up, and slightly longer than the PROCESS call.
57              
58             =cut
59              
60 2     2   10 use base qw( Template::Context );
  2         7  
  2         3479  
61 2     2   25090 use Time::HiRes ();
  2         3998  
  2         136  
62              
63             our $depth = 0;
64             our $epoch = undef;
65             our @totals;
66              
67             foreach my $sub ( qw( process include ) ) {
68 2     2   15 no strict;
  2         4  
  2         1037  
69             my $super = __PACKAGE__->can("SUPER::$sub") or die;
70             *{$sub} = sub {
71 2     2   68692 my $self = shift;
72 2         5 my $what = shift;
73              
74 0         0 my $template =
75             ref($what) eq 'ARRAY'
76 2 50       34 ? join( ' + ', @{$what} )
    50          
77             : ref($what)
78             ? $what->name
79             : $what;
80              
81 1         13 my $level;
82             my $processed_data;
83 0         0 my $epoch_elapsed_start;
84 0         0 my $epoch_elapsed_end;
85 1         14 my $now = [Time::HiRes::gettimeofday];
86 1         2 my $start = [@{$now}];
  1         3  
87 1         2 DOIT: {
88 1 50       2 local $epoch = $epoch ? $epoch : [@{$now}];
  1         5  
89 1         3 local $depth = $depth + 1;
90 1         2 $level = $depth;
91 1         4 $epoch_elapsed_start = _diff_disp($epoch);
92 1         43 $processed_data = $super->($self, $what, @_);
93 0         0 $epoch_elapsed_end = _diff_disp($epoch);
94             }
95 0         0 my $spacing = ' ' x $level;
96 0         0 my $level_elapsed = _diff_disp($start);
97 0         0 my $ip = uc substr( $sub, 0, 1 );
98 0         0 my $start_stats = "L$level $epoch_elapsed_start $spacing$ip $template";
99 0         0 my $end_stats = "L$level $epoch_elapsed_end $level_elapsed $spacing$ip $template";
100 0         0 @totals = ( $start_stats, @totals, $end_stats );
101 0 0       0 if ( $level > 1 ) {
102 0         0 return $processed_data;
103             }
104              
105 0         0 my $summary = join( "\n",
106             '<!-- SUMMARY',
107             @totals,
108             '-->',
109             '',
110             );
111 0         0 @totals = ();
112 0         0 return "$processed_data\n$summary\n";
113             }; # sub
114             } # for
115              
116              
117             sub _diff_disp {
118 1     1   2 my $starting_point = shift;
119              
120 1         6 return sprintf( '%7.3f', Time::HiRes::tv_interval($starting_point) * 1000 );
121             }
122              
123              
124             =head1 AUTHOR
125              
126             Andy Lester, C<< <andy at petdance.com> >>
127              
128             =head1 BUGS
129              
130             Please report any bugs or feature requests to
131             C<bug-template-timer at rt.cpan.org>, or through the web interface at
132             L<http://rt.cpan.org>. I will be notified, and then you'll automatically
133             be notified of progress on your bug as I make changes.
134              
135             =head1 ACKNOWLEDGEMENTS
136              
137             Thanks to
138             Randal Schwartz,
139             Bill Moseley,
140             and to Gavin Estey for the original code.
141              
142             =head1 COPYRIGHT & LICENSE
143              
144             This library is free software; you can redistribute it and/or modify
145             it under the terms of either the GNU Public License v3, or the Artistic
146             License 2.0.
147              
148             * http://www.gnu.org/copyleft/gpl.html
149              
150             * http://www.opensource.org/licenses/artistic-license-2.0.php
151              
152             =cut
153              
154             1; # End of Template::Timer