File Coverage

blib/lib/Benchmark/ProgressBar.pm
Criterion Covered Total %
statement 19 63 30.1
branch 0 32 0.0
condition 0 17 0.0
subroutine 7 9 77.7
pod 1 2 50.0
total 27 123 21.9


line stmt bran cond sub pod time code
1             # $Id$
2              
3             package Benchmark::ProgressBar;
4 1     1   7 use strict;
  1         2  
  1         39  
5 1     1   5 use warnings;
  1         3  
  1         31  
6 1     1   1016 use Benchmark;
  1         9107  
  1         9  
7 1     1   1354 use Term::ProgressBar;
  1         102798  
  1         146  
8             our $VERSION = '0.00001';
9              
10             sub import {
11 1     1   156 Benchmark->export_to_level(1, @_);
12             }
13              
14             package # hide from PAUSE
15             Benchmark;
16 1     1   10 use strict;
  1         3  
  1         41  
17 1     1   6 no warnings 'redefine';
  1         3  
  1         952  
18              
19             my $default_for = 3;
20             my $min_for = 0.1;
21              
22             our $ProgressTitle;
23              
24             sub runloop {
25 0     0 0   my($n, $c) = @_;
26              
27 0           $n+=0; # force numeric now, so garbage won't creep into the eval
28 0 0         croak "negative loopcount $n" if $n<0;
29 0 0         confess usage unless defined $c;
30 0           my($t0, $t1, $td); # before, after, difference
31              
32             # find package of caller so we can execute code there
33 0           my($curpack) = caller(0);
34 0           my($i, $pack)= 0;
35 0           while (($pack) = caller(++$i)) {
36 0 0         last if $pack ne $curpack;
37             }
38              
39 0   0       my $progress = Term::ProgressBar->new({ count => $n, remove => 1, name => $ProgressTitle || "progress" });
40 0           my ($subcode, $subref);
41 0 0         if (ref $c eq 'CODE') {
42 0           $subcode = "sub { for (1 .. $n) { local \$_; package $pack;
43             \$progress->update(\$_);
44             &\$c; } }";
45 0           $subref = eval $subcode;
46             }
47             else {
48 0           $subcode = "sub { for (1 .. $n) { local \$_; package $pack;
49             \$progress->update(\$_);
50             $c;} }";
51 0           $subref = _doeval($subcode);
52             }
53 0 0         croak "runloop unable to compile '$c': $@\ncode: $subcode\n" if $@;
54 0 0         print STDERR "runloop $n '$subcode'\n" if $Benchmark::Debug;
55              
56             # Give one more line so that the progress bar is easier on the eye
57             #print "\n";
58              
59             # Wait for the user timer to tick. This makes the error range more like
60             # -0.01, +0. If we don't wait, then it's more like -0.01, +0.01. This
61             # may not seem important, but it significantly reduces the chances of
62             # getting a too low initial $n in the initial, 'find the minimum' loop
63             # in &countit. This, in turn, can reduce the number of calls to
64             # &runloop a lot, and thus reduce additive errors.
65 0           my $tbase = Benchmark->new(0)->[1];
66 0           while ( ( $t0 = Benchmark->new(0) )->[1] == $tbase ) {} ;
67 0           $subref->();
68 0           $t1 = Benchmark->new($n);
69 0           $td = &timediff($t1, $t0);
70 0           timedebug("runloop:",$td);
71 0           $td;
72             }
73              
74             sub timethis{
75 0     0 1   my($n, $code, $title, $style) = @_;
76 0           my($t, $forn);
77              
78 0 0 0       die usage unless defined $code and
      0        
79             (!ref $code or ref $code eq 'CODE');
80              
81 0           local $ProgressTitle = $title;
82 0 0         if ( $n > 0 ) {
83 0 0         croak "non-integer loopcount $n, stopped" if int($n)<$n;
84 0           $t = timeit($n, $code);
85 0 0         $title = "timethis $n" unless defined $title;
86             } else {
87 0           my $fort = n_to_for( $n );
88 0           $t = countit( $fort, $code );
89 0 0         $title = "timethis for $fort" unless defined $title;
90 0           $forn = $t->[-1];
91             }
92 0           local $| = 1;
93 0 0         $style = "" unless defined $style;
94 0 0         printf("%10s: ", $title) unless $style eq 'none';
95 0 0         print timestr($t, $style, $Benchmark::Default_Format),"\n" unless $style eq 'none';
96              
97 0 0         $n = $forn if defined $forn;
98              
99             # A conservative warning to spot very silly tests.
100             # Don't assume that your benchmark is ok simply because
101             # you don't get this warning!
102 0 0 0       print " (warning: too few iterations for a reliable count)\n"
      0        
      0        
103             if $n < $Benchmark::Min_Count
104             || ($t->real < 1 && $n < 1000)
105             || $t->cpu_a < $Benchmark::Min_CPU;
106 0           $t;
107             }
108              
109              
110              
111             1;
112              
113             __END__