File Coverage

blib/lib/Dumbbench/Instance/PerlSub.pm
Criterion Covered Total %
statement 51 51 100.0
branch 8 8 100.0
condition 4 5 80.0
subroutine 13 13 100.0
pod 2 2 100.0
total 78 79 98.7


line stmt bran cond sub pod time code
1             package # hide from PAUSE
2             Dumbbench::Instance::PerlSub::_Lexical;
3             # clean lexical scope
4             sub runsub {
5 22     22   37 my $n = shift;
6 22         28 my $code = shift;
7 22         27 local $_;
8 22         40 for (1..$n) {
9 734         1502 $code->();
10             }
11             }
12              
13             package Dumbbench::Instance::PerlSub;
14 3     3   17 use strict;
  3         6  
  3         67  
15 3     3   14 use warnings;
  3         7  
  3         66  
16 3     3   16 use Carp ();
  3         6  
  3         41  
17 3     3   55 use Time::HiRes ();
  3         6  
  3         50  
18              
19 3     3   12 use Dumbbench::Instance;
  3         9  
  3         66  
20 3     3   10 use parent 'Dumbbench::Instance';
  3         5  
  3         13  
21              
22             use Class::XSAccessor {
23 3         25 getters => [qw(
24             code
25             dry_run_code
26             )],
27             accessors => [qw(
28             _n_loop_timings
29             _n_dry_loop_timings
30             )],
31 3     3   181 };
  3         4  
32              
33 3     3   896 use constant TOO_SMALL => 1.e-4;
  3         5  
  3         679  
34              
35             =encoding utf8
36              
37             =head1 NAME
38              
39             Dumbbench::Instance::PerlSub - Benchmarks a Perl code reference
40              
41             =head1 SYNOPSIS
42              
43             use Dumbbench;
44              
45             my $bench = Dumbbench->new(
46             target_rel_precision => 0.005, # seek ~0.5%
47             initial_runs => 20, # the higher the more reliable
48             );
49             $bench->add_instances(
50             Dumbbench::Instance::PerlSub->new(name => 'mauve', code => sub {...}),
51             # ... more things to benchmark ...
52             );
53             $bench->run();
54             # ...
55              
56             =head1 DESCRIPTION
57              
58             This class inherits from L and implements
59             benchmarking of Perl code references.
60              
61             =head1 METHODS
62              
63             =head2 new
64              
65             Constructor that takes named arguments.
66              
67             In addition to the properties of the base class, the
68             C constructor requires a
69             C parameter. The C needs to be subroutine reference.
70              
71             Optionally, you can provide a C option.
72             It has the same structure and purpose as the C
73             option, but it is used for the dry-runs. By default, an empty sub
74             is used for this, so it's unlikely you will need the dry-run
75             unless you want to strip out some particular overhead.
76              
77             =head2 code
78              
79             Returns the code string that was set during construction.
80              
81             =head2 dry_run_code
82              
83             Returns the dry-run code string that was set during construction.
84              
85             =cut
86              
87             # Note: We don't need to override clone() since we don't have composite attributes
88             # Note2: Can't (reliably) clone code refs anyway :(
89              
90             sub single_run {
91 2     2 1 5 my $self = shift;
92 2         4 return $self->_run(0);
93             }
94              
95             sub single_dry_run {
96 9     9 1 13 my $self = shift;
97 9         19 return $self->_run(1);
98             }
99              
100             sub _run {
101 11     11   22 my $self = shift;
102 11         14 my $dry = shift;
103 11 100       23 my $code_acc = $dry ? 'dry_run_code' : 'code';
104 11 100       21 my $n_loop_acc = $dry ? '_n_dry_loop_timings' : '_n_loop_timings';
105              
106 11         22 my $code = $self->$code_acc;
107 11 100 66 639   44 $code = sub {} if not ref($code) or not ref($code) eq 'CODE';
108              
109 11         19 my $duration;
110 11   100     56 my $n = $self->$n_loop_acc || 1;
111 11         17 while (1) {
112             #my $start;
113             #my $tbase = Time::HiRes::time();
114             #while ( ($start = Time::HiRes::time()) <= $tbase+1.e-15 ) {} # wait for clock tick. See discussion in Benchmark.pm comments
115 22         60 my $start = Time::HiRes::time();
116 22         41 Dumbbench::Instance::PerlSub::_Lexical::runsub($n, $code);
117 22         83 my $end = Time::HiRes::time();
118              
119 22         31 $duration = $end-$start;
120 22 100       45 if ($duration > TOO_SMALL) {
121 11         16 last;
122             }
123 11         17 $n *= 2;
124             }
125 11         26 $self->$n_loop_acc($n);
126              
127 11         40 return $duration / $n;
128             }
129              
130              
131              
132             1;
133              
134              
135             __END__