summaryrefslogtreecommitdiff
path: root/lib/Benchmark.pm
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-10-21 13:07:19 +0100
committerDavid Mitchell <davem@iabyn.com>2013-10-21 13:50:26 +0100
commit24755e36b3a8716d2d99c4ce1c1775c0807affa7 (patch)
treeaf82bf14a2e7f6f51eef6817f0790ae95cada080 /lib/Benchmark.pm
parent083ace8f9342a384107f7068fbedccaffa078b08 (diff)
downloadperl-24755e36b3a8716d2d99c4ce1c1775c0807affa7.tar.gz
Benchmark.pm: bail out earlier on zero delta
countit(), which runs code for $n seconds, performs an initial set of calibration loops to find out roughly how many iterations are required to burn 0.1 CPU secs more in the code loop than in the empty loop (which is then used to guesstimate how many iterations to do for the main loop). This calibration is designed to bail out if we consistently get <= 0 difference between the empty loop and the code loop; however, this bailout can take too long: it looks for a run of 17 *consecutive* zero deltas during 2048, 4096,8192,... iterations, which means it won't fail until approx 131 million empty + code iterations are run, even if the zeroes are consecutive. Of course if just by random noise one delta is infinitesimally > 0, then the count is reset and the exponential count continues. The net effect of this is that the calibration loop can loop forever on 'small' code. This commit makes it additionally bail out of the calibration loop if running the iterations for a particular value of N takes more than 8 CPU seconds, while still giving zero delta.
Diffstat (limited to 'lib/Benchmark.pm')
-rw-r--r--lib/Benchmark.pm18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/Benchmark.pm b/lib/Benchmark.pm
index e153435555..9a43a2bc60 100644
--- a/lib/Benchmark.pm
+++ b/lib/Benchmark.pm
@@ -482,7 +482,7 @@ our(@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
clearcache clearallcache disablecache enablecache);
%EXPORT_TAGS=( all => [ @EXPORT, @EXPORT_OK ] ) ;
-$VERSION = 1.17;
+$VERSION = 1.18;
# --- ':hireswallclock' special handling
@@ -772,11 +772,23 @@ sub countit {
# First find the minimum $n that gives a significant timing.
my $zeros=0;
for ($n = 1; ; $n *= 2 ) {
+ my $t0 = Benchmark->new(0);
my $td = timeit($n, $code);
+ my $t1 = Benchmark->new(0);
$tc = $td->[1] + $td->[2];
if ( $tc <= 0 and $n > 1024 ) {
- ++$zeros > 16
- and die "Timing is consistently zero in estimation loop, cannot benchmark. N=$n\n";
+ my $d = timediff($t1, $t0);
+ # note that $d is the total CPU time taken to call timeit(),
+ # while $tc is is difference in CPU secs between the empty run
+ # and the code run. If the code is trivial, its possible
+ # for $d to get large while $tc is still zero (or slightly
+ # negative). Bail out once timeit() starts taking more than a
+ # few seconds without noticeable difference.
+ if ($d->[1] + $d->[2] > 8
+ || ++$zeros > 16)
+ {
+ die "Timing is consistently zero in estimation loop, cannot benchmark. N=$n\n";
+ }
} else {
$zeros = 0;
}