Benchmark-Lab
view release on metacpan or search on metacpan
Use and feedback is welcome if you are willing to accept that risk.
SYNOPSIS
# Load as early as possible in case you want profiling
use Benchmark::Lab -profile => $ENV{DO_PROFILING};
# Define a task to benchmark as functions in a namespace
package My::Task;
# do once before any iterations (not timed)
sub setup {
my $context = shift;
...
}
# do before every iteration (not timed)
sub before_task {
my $context = shift;
...
}
my $context = shift;
...
}
# do after every iteration (not timed)
sub after_task {
my $context = shift;
...
}
# do once after all iterations (not timed)
sub teardown {
my $context = shift;
...
}
# Run benchmarks on a namespace
package main;
my $context = {}; # any data needed
name:
* "setup" â run once before any iteration begins (not timed)
* "before_task" â run before *each* "do_task" function (not timed)
* "do_task" â specific task being benchmarked (timed)
* "after_task" â run after *each* "do_task" function (not timed)
* "teardown" â run after all iterations are finished (not timed)
Each task phase will be called with a *context object*, which can be
used to pass data across phases.
package Foo;
sub setup {
my $context = shift;
$context->{filename} = "foobar.txt";
path($context->{filename})->spew_utf8( _test_data() );
use parent 'Foo::Base';
sub do_task { ... }
package Foo::Case2
use parent 'Foo::Base';
sub do_task { ... }
Running benchmarks
A "Benchmark::Lab" object defines the conditions of the test â currently
just the constraints on the number of iterations or duration of the
benchmarking run.
Running a benchmark is just a matter of specifying the namespace for the
task phase functions, and a context object, if desired.
use Benchmark::Lab -profile => $ENV{DO_PROFILE};
sub fact { my $n = int(shift); return $n == 1 ? 1 : $n * fact( $n - 1 ) }
*Fact::do_task = sub {
If parameters are omitted, $package defaults to "main", an empty hash
reference is used for the $context, and the $label defaults to the
$package.
It returns a hash reference with the following keys:
* "elapsed" â total wall clock time to execute the benchmark
(including non-timed portions).
* "total_time" â sum of recorded task iterations times.
* "iterations" â total number of "do_task" functions called.
* "percentiles" â hash reference with 1, 5, 10, 25, 50, 75, 90, 95 and
99th percentile iteration times. There may be duplicates if there
were fewer than 100 iterations.
* "median_rate" â the inverse of the 50th percentile time.
* "timing" â array reference with individual iteration times as
(floating point) seconds.
CAVEATS
If the "do_task" executes in less time than the timer granularity, an
error will be thrown. For benchmarks that do not have before/after
functions, just repeating the function under test in "do_task" will be
lib/Benchmark/Lab.pm view on Meta::CPAN
#pod
#pod If parameters are omitted, C<$package> defaults to "main", an empty
#pod hash reference is used for the C<$context>, and the C<$label> defaults
#pod to the C<$package>.
#pod
#pod It returns a hash reference with the following keys:
#pod
#pod =for :list
#pod * C<elapsed> â total wall clock time to execute the benchmark (including
#pod non-timed portions).
#pod * C<total_time> â sum of recorded task iterations times.
#pod * C<iterations> â total number of C<do_task> functions called.
#pod * C<percentiles> â hash reference with 1, 5, 10, 25, 50, 75, 90, 95 and
#pod 99th percentile iteration times. There may be duplicates if there were
#pod fewer than 100 iterations.
#pod * C<median_rate> â the inverse of the 50th percentile time.
#pod * C<timing> â array reference with individual iteration times as (floating
#pod point) seconds.
#pod
#pod =cut
sub start {
my ( $self, $package, $context, $label ) = @_;
$package ||= 'main';
$context ||= {};
lib/Benchmark/Lab.pm view on Meta::CPAN
$wall_time = $end_time - $wall_start;
}
DB::finish_profile() if $PROFILING;
my $pctiles = $self->_percentiles( \@timing );
return {
elapsed => $wall_time,
total_time => List::Util::sum( 0, @timing ),
iterations => scalar(@timing),
percentiles => $pctiles,
median_rate => 1 / $pctiles->{50},
timing => \@timing,
};
}
sub _log {
my $self = shift;
return unless $self->{verbose};
my @lines = map { chomp; "$_\n" } @_;
lib/Benchmark/Lab.pm view on Meta::CPAN
Use and feedback is welcome if you are willing to accept that risk.
=head1 SYNOPSIS
# Load as early as possible in case you want profiling
use Benchmark::Lab -profile => $ENV{DO_PROFILING};
# Define a task to benchmark as functions in a namespace
package My::Task;
# do once before any iterations (not timed)
sub setup {
my $context = shift;
...
}
# do before every iteration (not timed)
sub before_task {
my $context = shift;
...
}
lib/Benchmark/Lab.pm view on Meta::CPAN
my $context = shift;
...
}
# do after every iteration (not timed)
sub after_task {
my $context = shift;
...
}
# do once after all iterations (not timed)
sub teardown {
my $context = shift;
...
}
# Run benchmarks on a namespace
package main;
my $context = {}; # any data needed
lib/Benchmark/Lab.pm view on Meta::CPAN
=item *
C<do_task> â specific task being benchmarked (timed)
=item *
C<after_task> â run after I<each> C<do_task> function (not timed)
=item *
C<teardown> â run after all iterations are finished (not timed)
=back
Each task phase will be called with a I<context object>, which can be used
to pass data across phases.
package Foo;
sub setup {
my $context = shift;
lib/Benchmark/Lab.pm view on Meta::CPAN
sub do_task { ... }
package Foo::Case2
use parent 'Foo::Base';
sub do_task { ... }
=head2 Running benchmarks
A C<Benchmark::Lab> object defines the conditions of the test â currently
just the constraints on the number of iterations or duration of the
benchmarking run.
Running a benchmark is just a matter of specifying the namespace for the
task phase functions, and a context object, if desired.
use Benchmark::Lab -profile => $ENV{DO_PROFILE};
sub fact { my $n = int(shift); return $n == 1 ? 1 : $n * fact( $n - 1 ) }
*Fact::do_task = sub {
lib/Benchmark/Lab.pm view on Meta::CPAN
It returns a hash reference with the following keys:
=over 4
=item *
C<elapsed> â total wall clock time to execute the benchmark (including non-timed portions).
=item *
C<total_time> â sum of recorded task iterations times.
=item *
C<iterations> â total number of C<do_task> functions called.
=item *
C<percentiles> â hash reference with 1, 5, 10, 25, 50, 75, 90, 95 and 99th percentile iteration times. There may be duplicates if there were fewer than 100 iterations.
=item *
C<median_rate> â the inverse of the 50th percentile time.
=item *
C<timing> â array reference with individual iteration times as (floating point) seconds.
=back
( run in 1.627 second using v1.01-cache-2.11-cpan-71847e10f99 )