package Template::Timer; use warnings; use strict; =head1 NAME Template::Timer - Rudimentary profiling for Template Toolkit =head1 VERSION Version 1.00 =cut our $VERSION = '1.00'; =head1 SYNOPSIS Template::Timer provides inline timings of the template processing througout your code. It's an overridden version of L that wraps the C and C methods. Using Template::Timer is simple. use Template::Timer; my %config = ( # Whatever your config is INCLUDE_PATH => '/my/template/path', COMPILE_EXT => '.ttc', COMPILE_DIR => '/tmp/tt', ); if ( $development_mode ) { $config{ CONTEXT } = Template::Timer->new( %config ); } my $template = Template->new( \%config ); Now when you process templates, HTML comments will get embedded in your output, which you can easily grep for. The nesting level is also shown. .... Note that since INCLUDE is a wrapper around PROCESS, calls to INCLUDEs will be doubled up, and slightly longer than the PROCESS call. =cut use base qw( Template::Context ); use Time::HiRes (); our $depth = 0; our $epoch = undef; our @totals; foreach my $sub ( qw( process include ) ) { no strict; my $super = __PACKAGE__->can("SUPER::$sub") or die; *{$sub} = sub { my $self = shift; my $what = shift; my $template = ref($what) eq 'ARRAY' ? join( ' + ', @{$what} ) : ref($what) ? $what->name : $what; my $level; my $processed_data; my $epoch_elapsed_start; my $epoch_elapsed_end; my $now = [Time::HiRes::gettimeofday]; my $start = [@{$now}]; DOIT: { local $epoch = $epoch ? $epoch : [@{$now}]; local $depth = $depth + 1; $level = $depth; $epoch_elapsed_start = _diff_disp($epoch); $processed_data = $super->($self, $what, @_); $epoch_elapsed_end = _diff_disp($epoch); } my $spacing = ' ' x $level; my $level_elapsed = _diff_disp($start); my $ip = uc substr( $sub, 0, 1 ); my $start_stats = "L$level $epoch_elapsed_start $spacing$ip $template"; my $end_stats = "L$level $epoch_elapsed_end $level_elapsed $spacing$ip $template"; @totals = ( $start_stats, @totals, $end_stats ); if ( $level > 1 ) { return $processed_data; } my $summary = join( "\n", '', '', ); @totals = (); return "$processed_data\n$summary\n"; }; # sub } # for sub _diff_disp { my $starting_point = shift; return sprintf( '%7.3f', Time::HiRes::tv_interval($starting_point) * 1000 ); } =head1 AUTHOR Andy Lester, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 ACKNOWLEDGEMENTS Thanks to Randal Schwartz, Bill Moseley, and to Gavin Estey for the original code. =head1 COPYRIGHT & LICENSE This library is free software; you can redistribute it and/or modify it under the terms of either the GNU Public License v3, or the Artistic License 2.0. * http://www.gnu.org/copyleft/gpl.html * http://www.opensource.org/licenses/artistic-license-2.0.php =cut 1; # End of Template::Timer