=head1 SYNOPSIS
+ use Benchmark qw(:all) ;
+
timethis ($count, "code");
# Use Perl code in strings...
$count = $t->iters ;
print "$count loops of other code took:",timestr($t),"\n";
+ # enable hires wallclock timing if possible
+ use Benchmark ':hireswallclock';
+
=head1 DESCRIPTION
The Benchmark module encapsulates a number of routines to help you
Clear all cached times.
-=item cmpthese ( COUT, CODEHASHREF, [ STYLE ] )
+=item cmpthese ( COUNT, CODEHASHREF, [ STYLE ] )
=item cmpthese ( RESULTSHASHREF, [ STYLE ] )
=back
+=head2 :hireswallclock
+
+If the Time::HiRes module has been installed, you can specify the
+special tag C<:hireswallclock> for Benchmark (if Time::HiRes is not
+available, the tag will be silently ignored). This tag will cause the
+wallclock time to be measured in microseconds, instead of integer
+seconds. Note though that the speed computations are still conducted
+in CPU time, not wallclock time.
+
=head1 NOTES
The data is stored as a list of values from the time and times
For example,
- use Benchmark;$x=3;cmpthese(-5,{a=>sub{$x*$x},b=>sub{$x**2}})
+ use Benchmark qw( cmpthese ) ;
+ $x = 3;
+ cmpthese( -5, {
+ a => sub{$x*$x},
+ b => sub{$x**2},
+ } );
outputs something like this:
Benchmark: running a, b, each for at least 5 CPU seconds...
- a: 10 wallclock secs ( 5.14 usr + 0.13 sys = 5.27 CPU) @ 3835055.60/s (n=20210743)
- b: 5 wallclock secs ( 5.41 usr + 0.00 sys = 5.41 CPU) @ 1574944.92/s (n=8520452)
- Rate b a
- b 1574945/s -- -59%
- a 3835056/s 144% --
+ Rate b a
+ b 1559428/s -- -62%
+ a 4152037/s 166% --
+
while
- use Benchmark;
- $x=3;
- $r=timethese(-5,{a=>sub{$x*$x},b=>sub{$x**2}},'none');
- cmpthese($r);
+ use Benchmark qw( timethese cmpthese ) ;
+ $x = 3;
+ $r = timethese( -5, {
+ a => sub{$x*$x},
+ b => sub{$x**2},
+ } );
+ cmpthese $r;
outputs something like this:
- Rate b a
- b 1559428/s -- -62%
- a 4152037/s 166% --
+ Benchmark: running a, b, each for at least 5 CPU seconds...
+ a: 10 wallclock secs ( 5.14 usr + 0.13 sys = 5.27 CPU) @ 3835055.60/s (n=20210743)
+ b: 5 wallclock secs ( 5.41 usr + 0.00 sys = 5.41 CPU) @ 1574944.92/s (n=8520452)
+ Rate b a
+ b 1574945/s -- -59%
+ a 3835056/s 144% --
=head1 INHERITANCE
efficiency tweaks. Added cmpthese(). A result is now returned from
timethese(). Exposed countit() (was runfor()).
+December, 2001; by Nicholas Clark: make timestr() recognise the style 'none'
+and return an empty string. If cmpthese is calling timethese, make it pass the
+style in. (so that 'none' will suppress output). Make sub new dump its
+debugging output to STDERR, to be consistent with everything else.
+All bugs found while writing a regression test.
+
+September, 2002; by Jarkko Hietaniemi: add ':hireswallclock' special tag.
+
=cut
# evaluate something in a clean lexical environment
@EXPORT=qw(timeit timethis timethese timediff timestr);
@EXPORT_OK=qw(timesum cmpthese countit
clearcache clearallcache disablecache enablecache);
+%EXPORT_TAGS=( all => [ @EXPORT, @EXPORT_OK ] ) ;
+
+$VERSION = 1.0501;
-$VERSION = 1.01;
+# --- ':hireswallclock' special handling
+
+my $hirestime;
+
+sub mytime () { time }
&init;
+sub BEGIN {
+ if (eval 'require Time::HiRes') {
+ import Time::HiRes qw(time);
+ $hirestime = \&Time::HiRes::time;
+ }
+}
+
+sub import {
+ my $class = shift;
+ if (grep { $_ eq ":hireswallclock" } @_) {
+ @_ = grep { $_ ne ":hireswallclock" } @_;
+ *mytime = $hirestime if defined $hirestime;
+ }
+ Benchmark->export_to_level(1, $class, @_);
+}
+
sub init {
$debug = 0;
$min_count = 4;
# --- Functions to process the 'time' data type
-sub new { my @t = (time, times, @_ == 2 ? $_[1] : 0);
- print "new=@t\n" if $debug;
+sub new { my @t = (mytime, times, @_ == 2 ? $_[1] : 0);
+ print STDERR "new=@t\n" if $debug;
bless \@t; }
sub cpu_p { my($r,$pu,$ps,$cu,$cs) = @{$_[0]}; $pu+$ps ; }
$f = $defaultfmt unless defined $f;
# format a time in the required style, other formats may be added here
$style ||= $defaultstyle;
+ return '' if $style eq 'none';
$style = ($ct>0) ? 'all' : 'noc' if $style eq 'auto';
my $s = "@t $style"; # default for unknown style
- $s=sprintf("%2d wallclock secs (%$f usr %$f sys + %$f cusr %$f csys = %$f CPU)",
+ my $w = $hirestime ? "%2g" : "%2d";
+ $s=sprintf("$w wallclock secs (%$f usr %$f sys + %$f cusr %$f csys = %$f CPU)",
$r,$pu,$ps,$cu,$cs,$tt) if $style eq 'all';
- $s=sprintf("%2d wallclock secs (%$f usr + %$f sys = %$f CPU)",
+ $s=sprintf("$w wallclock secs (%$f usr + %$f sys = %$f CPU)",
$r,$pu,$ps,$pt) if $style eq 'noc';
- $s=sprintf("%2d wallclock secs (%$f cusr + %$f csys = %$f CPU)",
+ $s=sprintf("$w wallclock secs (%$f cusr + %$f csys = %$f CPU)",
$r,$cu,$cs,$ct) if $style eq 'nop';
$s .= sprintf(" @ %$f/s (n=$n)", $n / ( $pu + $ps )) if $n && $pu+$ps;
$s;
if ($cache && exists $cache{$cache_key} ) {
$wn = $cache{$cache_key};
} else {
- $wn = &runloop($n, ref( $code ) ? sub { undef } : '' );
+ $wn = &runloop($n, ref( $code ) ? sub { } : '' );
# Can't let our baseline have any iterations, or they get subtracted
# out of the result.
$wn->[5] = 0;
print " ", join(', ',@names) unless $style eq 'none';
unless ( $n > 0 ) {
my $for = n_to_for( $n );
- print ", each for at least $for CPU seconds" unless $style eq 'none';
+ print ", each" if $n > 1 && $style ne 'none';
+ print " for at least $for CPU seconds" unless $style eq 'none';
}
print "...\n" unless $style eq 'none';
}
sub cmpthese{
- my ($results, $style) = ref $_[0] ? @_ : ( timethese( @_[0,1] ), $_[2] ) ;
+ my ($results, $style) =
+ ref $_ [0] ? @_
+ : (timethese (@_ [0, 1], @_ > 2 ? $_ [2] : "none"), $_ [2]);
$style = "" unless defined $style;