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 23     23   25 my $n = shift;
6 23         23 my $code = shift;
7 23         23 local $_;
8 23         30 for (1..$n) {
9 798         946 $code->();
10             }
11             }
12              
13             package Dumbbench::Instance::PerlSub;
14 3     3   16 use strict;
  3         5  
  3         67  
15 3     3   11 use warnings;
  3         5  
  3         53  
16 3     3   10 use Carp ();
  3         6  
  3         39  
17 3     3   10 use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
  3         4  
  3         15  
18              
19 3     3   270 use Dumbbench::Instance;
  3         5  
  3         73  
20 3     3   14 use parent 'Dumbbench::Instance';
  3         5  
  3         18  
21              
22             use Class::XSAccessor {
23 3         18 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   237 };
  3         4  
32              
33 3     3   807 use constant TOO_SMALL => 1.e-4;
  3         5  
  3         718  
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 4 my $self = shift;
92 2         6 return $self->_run(0);
93             }
94              
95             sub single_dry_run {
96 10     10 1 12 my $self = shift;
97 10         14 return $self->_run(1);
98             }
99              
100             sub _run {
101 12     12   14 my $self = shift;
102 12         14 my $dry = shift;
103 12 100       18 my $code_acc = $dry ? 'dry_run_code' : 'code';
104 12 100       17 my $n_loop_acc = $dry ? '_n_dry_loop_timings' : '_n_loop_timings';
105              
106 12         17 my $code = $self->$code_acc;
107 12 100 66 703   42 $code = sub {} if not ref($code) or not ref($code) eq 'CODE';
108              
109 12         13 my $duration;
110 12   100     26 my $n = $self->$n_loop_acc || 1;
111 12         13 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 23         39 my $start = clock_gettime(CLOCK_MONOTONIC);
116 23         70 Dumbbench::Instance::PerlSub::_Lexical::runsub($n, $code);
117 23         47 my $end = clock_gettime(CLOCK_MONOTONIC);
118              
119 23         51 $duration = $end-$start;
120 23 100       34 if ($duration > TOO_SMALL) {
121 12         13 last;
122             }
123 11         12 $n *= 2;
124             }
125 12         25 $self->$n_loop_acc($n);
126              
127 12         35 return $duration / $n;
128             }
129              
130              
131              
132             1;
133              
134              
135             __END__