1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#!/usr/bin/perl
use v5.14;
use warnings;
use Test2::V0;
# This "test" never fails, but prints a benchmark comparison between
# Data::Checks and Types::Standard performing the same :Checked attribute
# assertions on a function. It also compares against a manually-written check
# for interest.
BEGIN {
eval { require Signature::Attribute::Checked;
Signature::Attribute::Checked->VERSION( '0.04' ) } or
plan skip_all => "Signature::Attribute::Checked >= 0.04 is not available";
eval { require Types::Standard } or
plan skip_all => "Types::Standard is not available";
}
use Time::HiRes qw( gettimeofday tv_interval );
sub measure(&)
{
my ( $code ) = @_;
my $start = [ gettimeofday ];
$code->();
return tv_interval $start;
}
use Sublike::Extended 0.29 'sub';
use Signature::Attribute::Checked;
use Data::Checks;
use Types::Standard;
use experimental qw( signatures );
sub func_DC ( $x :Checked(Data::Checks::Defined) ) { return $x; }
sub func_TS ( $x :Checked(Types::Standard::Defined) ) { return $x; }
sub func_manual ( $x ) {
defined $x or die "Require defined value for \$x";
return $x;
}
my $COUNT = 50_000;
my $elapsed_DC = 0;
my $elapsed_TS = 0;
my $elapsed_manual= 0;
# To reduce the influence of bursts of timing noise, interleave many small runs
# of each type.
foreach ( 1 .. 20 ) {
my $overhead = measure {};
$elapsed_DC += -$overhead + measure {
func_DC( 123 ) for 1 .. $COUNT;
};
$elapsed_TS += -$overhead + measure {
func_TS( 123 ) for 1 .. $COUNT;
};
$elapsed_manual += -$overhead + measure {
func_manual( 123 ) for 1 .. $COUNT;
};
}
pass( "Benchmarked" );
if( $elapsed_DC > $elapsed_TS ) {
diag( sprintf "Types::Standard took %.3fsec, ** this was SLOWER at %.3fsec **",
$elapsed_TS, $elapsed_DC );
}
else {
my $speedup = ( $elapsed_TS - $elapsed_DC ) / $elapsed_TS;
diag( sprintf "Types::Standard took %.3fsec, this was %d%% faster at %.3fsec",
$elapsed_TS, $speedup * 100, $elapsed_DC );
}
my $speedup = ( $elapsed_manual - $elapsed_DC ) / $elapsed_manual;
if( $elapsed_DC > $elapsed_manual ) {
diag( sprintf "manual took %.3fsec, this was %d%% slower at %.3fsec",
$elapsed_manual, -$speedup * 100, $elapsed_DC );
}
else {
diag( sprintf "manual took %.3fsec, this was %d%% faster at %.3fsec",
$elapsed_manual, $speedup * 100, $elapsed_DC );
}
done_testing;
|