public

Speed comparison between Type::Params and Params::Validate (PP and XS)

  • Download Gist
benchmark-param-validation-practical.pl
Perl
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 93 94 95 96 97 98 99 100 101 102 103
use 5.012;
use Benchmark qw( cmpthese timethese );
use Test::Deep::NoTest;
 
use Scalar::Util qw(looks_like_number);
use Params::Validate qw(SCALAR HASHREF ARRAYREF);
my @SIG = (
{ type => SCALAR, callbacks => { looks_like_number => sub { looks_like_number($_[0]) } } },
{ type => HASHREF },
{ type => ARRAYREF },
);
 
{
package UsingParamsValidateXS;
use Params::Validate qw(validate_pos);
sub hash_plus {
my ($number, $hash, $keys) = validate_pos(@_, @SIG);
my %clone = %$hash;
$clone{$_} += $number for @$keys;
return \%clone;
}
}
 
{
package UsingParamsValidatePP;
use Params::Validate::PP;
sub hash_plus {
my ($number, $hash, $keys) = Params::Validate::PP::validate_pos(@_, @SIG);
my %clone = %$hash;
$clone{$_} += $number for @$keys;
return \%clone;
}
}
 
{
package UsingTypeParams;
use Type::Params qw(compile);
use Types::Standard qw( Num HashRef ArrayRef );
sub hash_plus {
state $check = compile(Num, HashRef, ArrayRef);
my ($number, $hash, $keys) = $check->(@_);
my %clone = %$hash;
$clone{$_} += $number for @$keys;
return \%clone;
}
}
 
{
package UsingSnail;
use Type::Params qw(compile);
use Types::Standard qw( Num HashRef ArrayRef );
sub hash_plus {
my $check = compile(Num, HashRef, ArrayRef);
my ($number, $hash, $keys) = $check->(@_);
my %clone = %$hash;
$clone{$_} += $number for @$keys;
return \%clone;
}
}
 
{
package UsingTypeParamsStricter;
use Type::Params qw(compile);
use Types::Standard qw( Num HashRef ArrayRef Str );
sub hash_plus {
state $check = compile(Num, HashRef[Num], ArrayRef[Str]);
my ($number, $hash, $keys) = $check->(@_);
my %clone = %$hash;
$clone{$_} += $number for @$keys;
return \%clone;
}
}
 
@::input = (7, { foo => 1, bar => 2, baz => 3 }, [qw/foo bar/]);
$::expected = { foo => 8, bar => 9, baz => 3 };
 
my %all;
for my $impl (qw/ UsingParamsValidateXS UsingParamsValidatePP UsingTypeParams /)
{
my $code = $impl->can("hash_plus");
die "bad implementation: $impl!\n" unless eq_deeply($code->(@::input), $::expected);
$all{$impl} = sprintf('%s::hash_plus(@::input)', $impl);
}
 
cmpthese(-3, \%all);
 
__END__
Rate UsingParamsValidatePP UsingParamsValidateXS UsingTypeParams
UsingParamsValidatePP 5071/s -- -64% -85%
UsingParamsValidateXS 14052/s 177% -- -59%
UsingTypeParams 34252/s 575% 144% --

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.