File Coverage

blib/lib/Bench.pm
Criterion Covered Total %
statement 23 63 36.5
branch 1 26 3.8
condition 1 15 6.6
subroutine 9 11 81.8
pod 1 1 100.0
total 35 116 30.1


line stmt bran cond sub pod time code
1             package Bench;
2              
3             our $VERSION = '0.10'; # VERSION
4              
5 1     1   31090 use 5.010001;
  1         5  
  1         42  
6 1     1   6 use strict;
  1         2  
  1         31  
7 1     1   5 use warnings;
  1         1  
  1         42  
8              
9 1     1   2035 use Time::HiRes qw/gettimeofday tv_interval/;
  1         2339  
  1         5  
10              
11             my $bench_called;
12             my ($t0, $ti);
13              
14             sub _set_start_time {
15 1     1   9 $t0 = [gettimeofday];
16             }
17              
18             sub _set_interval {
19 1     1   17 $ti = tv_interval($t0, [gettimeofday]);
20             }
21              
22             sub import {
23 1     1   9 _set_start_time;
24 1     1   315 no strict 'refs';
  1         2  
  1         786  
25 1         2 my $caller = caller();
26 1         2 *{"$caller\::bench"} = \&bench;
  1         2107  
27             }
28              
29             sub _fmt_num {
30 0     0     my ($num, $unit, $nsig) = @_;
31 0   0       $nsig //= 4;
32 0           my $fmt;
33              
34 0 0         my $l = $num ? int(log(abs($num))/log(10)) : 0;
35 0 0         if ($l >= $nsig) {
    0          
36 0           $fmt = "%.0f";
37             } elsif ($l < 0) {
38 0           $fmt = "%.${nsig}f";
39             } else {
40 0           $fmt = "%.".($nsig-$l-1)."f";
41             }
42             #say "D:fmt=$fmt";
43 0   0       sprintf($fmt, $num) . ($unit // "");
44             }
45              
46             sub bench($;$) {
47 0     0 1   my ($subs0, $opts) = @_;
48 0   0       $opts //= {};
49 0 0         $opts = {n=>$opts} if ref($opts) ne 'HASH';
50 0   0       $opts->{t} //= 1;
51 0   0       $opts->{n} //= 100;
52 0           my %subs;
53 0 0         if (ref($subs0) eq 'CODE') {
    0          
    0          
54 0           %subs = (a=>$subs0);
55             } elsif (ref($subs0) eq 'HASH') {
56 0           %subs = %$subs0;
57             } elsif (ref($subs0) eq 'ARRAY') {
58 0           my $name = "a";
59 0           for (@$subs0) { $subs{$name++} = $_ }
  0            
60             } else {
61 0           die "Usage: bench(CODE|{a=>CODE,b=>CODE, ...}|[CODE, CODE, ...], ".
62             "{opt=>val, ...})";
63             }
64 0 0         die "Please specify one or more subs"
65             unless keys %subs;
66              
67 0           my $use_dumbbench;
68 0 0         if ($opts->{dumbbench}) {
    0          
69 0           $use_dumbbench++;
70 0           require Dumbbench;
71             } elsif (!defined $opts->{dumbbench}) {
72 0 0         $use_dumbbench++ if $INC{"Dumbbench.pm"};
73             }
74              
75 0           my $void = !defined(wantarray);
76 0 0         if ($use_dumbbench) {
77              
78 0   0       $opts->{dumbbench_options} //= {};
79 0           my $bench = Dumbbench->new(%{ $opts->{dumbbench_options} });
  0            
80 0           $bench->add_instances(
81 0           map { Dumbbench::Instance::PerlSub->new(code => $subs{$_}) }
82             keys %subs
83             );
84 0           $bench->run;
85 0           $bench->report;
86              
87             } else {
88 0           require Benchmark;
89 0           Benchmark::timethese(
90             $opts->{n},
91             \%subs,
92             );
93             }
94              
95 0           $bench_called++;
96             }
97              
98             END {
99 1     1   629 _set_interval;
100 1 50 33     23 say _fmt_num($ti, "s") unless $bench_called || $ENV{HARNESS_ACTIVE};
101             }
102              
103             1;
104             # ABSTRACT: Benchmark running times of Perl code
105              
106             __END__