| 1 | #!./perl -w
|
|---|
| 2 |
|
|---|
| 3 | BEGIN {
|
|---|
| 4 | chdir 't' if -d 't';
|
|---|
| 5 | @INC = ('../lib');
|
|---|
| 6 | }
|
|---|
| 7 |
|
|---|
| 8 | use warnings;
|
|---|
| 9 | use strict;
|
|---|
| 10 | use vars qw($foo $bar $baz $ballast);
|
|---|
| 11 | use Test::More tests => 194;
|
|---|
| 12 |
|
|---|
| 13 | use Benchmark qw(:all);
|
|---|
| 14 |
|
|---|
| 15 | my $delta = 0.4;
|
|---|
| 16 |
|
|---|
| 17 | # Some timing ballast
|
|---|
| 18 | sub fib {
|
|---|
| 19 | my $n = shift;
|
|---|
| 20 | return $n if $n < 2;
|
|---|
| 21 | fib($n-1) + fib($n-2);
|
|---|
| 22 | }
|
|---|
| 23 | $ballast = 15;
|
|---|
| 24 |
|
|---|
| 25 | my $All_Pattern =
|
|---|
| 26 | qr/(\d+) +wallclock secs? +\( *(-?\d+\.\d\d) +usr +(-?\d+\.\d\d) +sys +\+ +(-?\d+\.\d\d) +cusr +(-?\d+\.\d\d) +csys += +(-?\d+\.\d\d) +CPU\)/;
|
|---|
| 27 | my $Noc_Pattern =
|
|---|
| 28 | qr/(\d+) +wallclock secs? +\( *(-?\d+\.\d\d) +usr +\+ +(-?\d+\.\d\d) +sys += +(-?\d+\.\d\d) +CPU\)/;
|
|---|
| 29 | my $Nop_Pattern =
|
|---|
| 30 | qr/(\d+) +wallclock secs? +\( *(-?\d+\.\d\d) +cusr +\+ +(-?\d+\.\d\d) +csys += +\d+\.\d\d +CPU\)/;
|
|---|
| 31 | # Please don't trust the matching parenthises to be useful in this :-)
|
|---|
| 32 | my $Default_Pattern = qr/$All_Pattern|$Noc_Pattern/;
|
|---|
| 33 |
|
|---|
| 34 | my $t0 = new Benchmark;
|
|---|
| 35 | isa_ok ($t0, 'Benchmark', "Ensure we can create a benchmark object");
|
|---|
| 36 |
|
|---|
| 37 | # We use the benchmark object once we've done some work:
|
|---|
| 38 |
|
|---|
| 39 | isa_ok(timeit(5, sub {++$foo}), 'Benchmark', "timeit CODEREF");
|
|---|
| 40 | is ($foo, 5, "benchmarked code was run 5 times");
|
|---|
| 41 |
|
|---|
| 42 | isa_ok(timeit(5, '++$bar'), 'Benchmark', "timeit eval");
|
|---|
| 43 | is ($bar, 5, "benchmarked code was run 5 times");
|
|---|
| 44 |
|
|---|
| 45 | # is coderef called with spurious arguments?
|
|---|
| 46 | timeit( 1, sub { $foo = @_ });
|
|---|
| 47 | is ($foo, 0, "benchmarked code called without arguments");
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 | print "# Burning CPU to benchmark things will take time...\n";
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 | # We need to do something fairly slow in the coderef.
|
|---|
| 55 | # Same coderef. Same place in memory.
|
|---|
| 56 | my $coderef = sub {$baz += fib($ballast)};
|
|---|
| 57 |
|
|---|
| 58 | # The default is three.
|
|---|
| 59 | $baz = 0;
|
|---|
| 60 | my $threesecs = countit(0, $coderef);
|
|---|
| 61 | isa_ok($threesecs, 'Benchmark', "countit 0, CODEREF");
|
|---|
| 62 | isnt ($baz, 0, "benchmarked code was run");
|
|---|
| 63 | my $in_threesecs = $threesecs->iters;
|
|---|
| 64 | print "# $in_threesecs iterations\n";
|
|---|
| 65 | ok ($in_threesecs > 0, "iters returned positive iterations");
|
|---|
| 66 |
|
|---|
| 67 | my $estimate = int (100 * $in_threesecs / 3) / 100;
|
|---|
| 68 | print "# from the 3 second run estimate $estimate iterations in 1 second...\n";
|
|---|
| 69 | $baz = 0;
|
|---|
| 70 | my $onesec = countit(1, $coderef);
|
|---|
| 71 | isa_ok($onesec, 'Benchmark', "countit 1, CODEREF");
|
|---|
| 72 | isnt ($baz, 0, "benchmarked code was run");
|
|---|
| 73 | my $in_onesec = $onesec->iters;
|
|---|
| 74 | print "# $in_onesec iterations\n";
|
|---|
| 75 | ok ($in_onesec > 0, "iters returned positive iterations");
|
|---|
| 76 |
|
|---|
| 77 | {
|
|---|
| 78 | my $difference = $in_onesec - $estimate;
|
|---|
| 79 | my $actual = abs ($difference / $in_onesec);
|
|---|
| 80 | ok ($actual < $delta, "is $in_onesec within $delta of estimate ($estimate)");
|
|---|
| 81 | print "# $in_onesec is between " . ($delta / 2) .
|
|---|
| 82 | " and $delta of estimate. Not that safe.\n" if $actual > $delta/2;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | # I found that the eval'ed version was 3 times faster than the coderef.
|
|---|
| 86 | # (now it has a different ballast value)
|
|---|
| 87 | $baz = 0;
|
|---|
| 88 | my $again = countit(1, '$baz += fib($ballast)');
|
|---|
| 89 | isa_ok($onesec, 'Benchmark', "countit 1, eval");
|
|---|
| 90 | isnt ($baz, 0, "benchmarked code was run");
|
|---|
| 91 | my $in_again = $again->iters;
|
|---|
| 92 | print "# $in_again iterations\n";
|
|---|
| 93 | ok ($in_again > 0, "iters returned positive iterations");
|
|---|
| 94 |
|
|---|
| 95 |
|
|---|
| 96 | my $t1 = new Benchmark;
|
|---|
| 97 | isa_ok ($t1, 'Benchmark', "Create another benchmark object now we're finished");
|
|---|
| 98 |
|
|---|
| 99 | my $diff = timediff ($t1, $t0);
|
|---|
| 100 | isa_ok ($diff, 'Benchmark', "Get the time difference");
|
|---|
| 101 | isa_ok (timesum ($t0, $t1), 'Benchmark', "check timesum");
|
|---|
| 102 |
|
|---|
| 103 | my $default = timestr ($diff);
|
|---|
| 104 | isnt ($default, '', 'timestr ($diff)');
|
|---|
| 105 | my $auto = timestr ($diff, 'auto');
|
|---|
| 106 | is ($auto, $default, 'timestr ($diff, "auto") matches timestr ($diff)');
|
|---|
| 107 |
|
|---|
| 108 | {
|
|---|
| 109 | my $all = timestr ($diff, 'all');
|
|---|
| 110 | like ($all, $All_Pattern, 'timestr ($diff, "all")');
|
|---|
| 111 | print "# $all\n";
|
|---|
| 112 |
|
|---|
| 113 | my ($wallclock, $usr, $sys, $cusr, $csys, $cpu) = $all =~ $All_Pattern;
|
|---|
| 114 |
|
|---|
| 115 | is (timestr ($diff, 'none'), '', "none supresses output");
|
|---|
| 116 |
|
|---|
|
|---|