Forked from tobyink/benchmark-param-validation-practical.pl
Last active
September 24, 2017 03:11
-
-
Save mohawk2/7537ad627b01ec55f4bd1adcbf788727 to your computer and use it in GitHub Desktop.
Speed comparison between Type::Params and Params::Validate (PP and XS) and Function::Parameters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
{ | |
package UsingFP; | |
use Function::Parameters; | |
use Types::Standard qw( Num HashRef ArrayRef Str ); | |
fun hash_plus(Num $number, HashRef[Num] $hash, ArrayRef[Str] $keys) { | |
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 UsingTypeParamsStricter UsingFP /) | |
{ | |
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 UsingFP UsingTypeParamsStricter | |
UsingParamsValidatePP 19567/s -- -69% -73% -80% | |
UsingParamsValidateXS 63951/s 227% -- -13% -36% | |
UsingFP 73569/s 276% 15% -- -27% | |
UsingTypeParamsStricter 100200/s 412% 57% 36% -- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment