File Coverage

blib/lib/Dumbbench/Instance/PerlEval.pm
Criterion Covered Total %
statement 51 51 100.0
branch 8 8 100.0
condition 2 2 100.0
subroutine 12 12 100.0
pod 2 2 100.0
total 75 75 100.0


line stmt bran cond sub pod time code
1             package # hide from PAUSE
2             Dumbbench::Instance::PerlEval::_Lexical;
3             # clean lexical scope
4             sub doeval {
5 53     53   65 local $_ = shift;
6 53         80 for (1..$_) {
7 509         682 local $_;
8 509         423 eval ${shift()};
  509         4855  
9             }
10             }
11              
12             package Dumbbench::Instance::PerlEval;
13 3     3   15 use strict;
  3         7  
  3         73  
14 3     3   12 use warnings;
  3         5  
  3         61  
15 3     3   12 use Carp ();
  3         3  
  3         62  
16 3     3   13 use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
  3         4  
  3         23  
17              
18 3     3   276 use Dumbbench::Instance;
  3         4  
  3         77  
19 3     3   15 use parent 'Dumbbench::Instance';
  3         5  
  3         14  
20              
21             use Class::XSAccessor {
22 3         21 getters => [qw(
23             code
24             dry_run_code
25             )],
26             accessors => [qw(
27             _n_loop_timings
28             _n_dry_loop_timings
29             )],
30 3     3   194 };
  3         4  
31              
32 3     3   838 use constant TOO_SMALL => 1.e-4;
  3         5  
  3         781  
33              
34             =encoding utf8
35              
36             =head1 NAME
37              
38             Dumbbench::Instance::PerlEval - Benchmarks a string of Perl code
39              
40             =head1 SYNOPSIS
41              
42             use Dumbbench;
43              
44             my $bench = Dumbbench->new(
45             target_rel_precision => 0.005, # seek ~0.5%
46             initial_runs => 20, # the higher the more reliable
47             );
48             $bench->add_instances(
49             Dumbbench::Instance::PerlEval->new(name => 'mauve', code => 'for(1..1e9){$i++}'),
50             # ... more things to benchmark ...
51             );
52             $bench->run();
53             # ...
54              
55             =head1 DESCRIPTION
56              
57             This class inherits from L and implements
58             benchmarking of strings of Perl code using C.
59              
60             =head1 METHODS
61              
62             =head2 new
63              
64             Constructor that takes named arguments.
65              
66             In addition to the properties of the base class, the
67             C constructor requires a
68             C parameter. The C needs to be a string that
69             is suitable for passing repeatedly to string-C.
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, a simple
74             C is used for this, so it's unlikely you will need the dry-run
75             unless you want to strip out the compile-time overhead of your code.
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              
89             sub single_run {
90 6     6 1 11 my $self = shift;
91 6         18 return $self->_run(0);
92             }
93              
94             sub single_dry_run {
95 26     26 1 34 my $self = shift;
96 26         40 return $self->_run(1);
97             }
98              
99             sub _run {
100 32     32   33 my $self = shift;
101 32         32 my $dry = shift;
102 32 100       59 my $code_acc = $dry ? 'dry_run_code' : 'code';
103 32 100       46 my $n_loop_acc = $dry ? '_n_dry_loop_timings' : '_n_loop_timings';
104              
105 32         101 my $code = $self->$code_acc;
106 32 100       55 $code = '' if not defined $code;
107              
108 32         33 my $duration;
109 32   100     70 my $n = $self->$n_loop_acc || 1;
110 32         32 while (1) {
111             #my $start;
112             #my $tbase = Time::HiRes::time();
113             #while ( ($start = Time::HiRes::time()) <= $tbase+1.e-15 ) {} # wait for clock tick. See discussion in Benchmark.pm comments
114 53         92 my $start = clock_gettime(CLOCK_MONOTONIC);
115 53         191 Dumbbench::Instance::PerlEval::_Lexical::doeval($n, \$code);
116 53         123 my $end = clock_gettime(CLOCK_MONOTONIC);
117              
118 53         144 $duration = $end-$start;
119 53 100       90 if ($duration > TOO_SMALL) {
120 32         37 last;
121             }
122 21         28 $n *= 2;
123             }
124 32         76 $self->$n_loop_acc($n);
125              
126 32         95 return $duration / $n;
127             }
128              
129              
130              
131             1;
132              
133              
134             __END__