package ActiveState::StopWatch; use strict; BEGIN { eval { require Time::HiRes; Time::HiRes->import('time'); }; } use base 'Exporter'; our @EXPORT = qw(start_watch stop_watch); our @EXPORT_OK = qw(real_time read_watch); my @LABELS = qw(r u s cu cs); sub start_watch { return [time, times] unless @_; my $w = shift; return unless @$w > @LABELS; # not stopped my @t = (time, times); my @p = splice(@$w, @LABELS); for (@$w) { $_ += shift(@t) - shift(@p); } } sub read_watch { my @w = @{shift(@_)}; my @t = @w > @LABELS ? @w[@LABELS .. $#w] : (time, times); for (@t) { $_ -= shift @w; } # drop child times if they are 0 pop(@t) unless $t[-1]; pop(@t) unless $t[-1]; my @labels = @LABELS; for (@t) { if ($_ > 60 || ($labels[0] eq "r" && !$Time::HiRes::VERSION)) { $_ = sprintf "%s=%.0fs", shift(@labels), $_; } elsif ($_ > 15) { $_ = sprintf "%s=%.1fs", shift(@labels), $_; } elsif ($_ == 0) { $_ = sprintf "%s=0", shift(@labels); } else { $_ = sprintf "%s=%.2fs", shift(@labels), $_; } } return "@t"; } sub stop_watch { my $w = shift; push(@$w, time, times) unless @$w > @LABELS; # already stopped return read_watch($w) if defined wantarray; } sub real_time { my $w = shift; return time - $w->[0]; } 1; =head1 NAME ActiveState::StopWatch - Time code =head1 SYNOPSIS use ActiveState::StopWatch qw(start_watch stop_watch read_watch real_time); my $w = start_watch(); # ... do stuff ... print read_watch($w); # ... do stuff ... print stop_watch($w); # restart it start_watch($w); print stop_watch($w); =head1 DESCRIPTION The ActiveState::StopWatch module provide functions that can be used to measure the time spent by sections of code. The following functions are provided: =over =item $w = start_watch() =item start_watch( $w ) Without argument this function creates a new watch object. With argument it can restart a watch that has been stopped after invoking the stop_watch() function on it. If the watch provided is not stopped then its state is not affected. =item $str = read_watch( $w ) This function returns a string that tells how much real, user and system time has ticked during the time the watch has been running. The string will look like this: r=12.5s u=4.90s s=0.55s cu=1.22s cs=0.22s The 'cu' and 'cs' field gives time spent in children of the current process during the time the watch has been running. The child fields are not shown if they are 0. =item $str = stop_watch( $w ) This function return a string of the same format as for read_watch(), but it will also stop the clock from running. This means that read_watch() will continue to return the same result. The watch can be restarted by calling start_watch() with the watch object as argument. =item $r = real_time( $w ) This function returns the number of seconds of real time passed during the time the watch has been running. =back Only the start_watch() and stop_watch() functions are exported by default. =head1 COPYRIGHT Copyright (C) 2003 ActiveState Corp. All rights reserved. =cut