Skip Menu |
 

This queue is for tickets about the Params-Check CPAN distribution.

Report information
The Basics
Id: 27161
Status: open
Priority: 0/
Queue: Params-Check

People
Owner: Nobody in particular
Requestors: DAMS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Enhancement proposal
Download (untitled) / with headers
text/plain 757b
Hi, I've worked on a reimplementation of this module for use in my company. Here is the version I ended with, that is backward compatible, contains the existing features, add 1 new feature, has the same code size, but is (sometimes really) faster. Attached are : - My implementation (file Check.pm) - The patch agains 0.26 version (file faster_reimpl.patch) - A benchmark file (file benchmark.pl) - The benchmark result, that I have commented (file result.txt) The new feature is that if you ask the template to store the value into a reference on a hash or array, then it's stored directyl in the array or hash. Thus you can write : my @array; check({ foo => { default => [], store => \@array} }, { foo => [ 42 ] } # @array is ( 42 ); Enjoy ! :) dams
Subject: result.txt
Download result.txt
text/plain 3.3k
*** store2 Rate orig new orig 28169/s -- -18% new 34483/s 22% -- *** subs1 Rate orig new orig 25316/s -- -37% new 40000/s 58% -- # no difference, same code is run *** no_override Rate orig new orig 16129/s -- -8% new 17544/s 9% -- # first run is valid arg, second is broken arg # new code is optimized for valid args *** strict2 Rate orig new orig 27397/s -- -40% new 45455/s 66% -- Rate orig new orig 19231/s -- -13% new 21978/s 14% -- *** edge_case Rate orig new orig 37975/s -- -35% new 58824/s 55% -- *** preserver_case2 Rate orig new orig 15385/s -- -11% new 17241/s 12% -- # first run is valid arg, second is broken arg # new code is optimized for valid args *** required Rate orig new orig 29851/s -- -40% new 50000/s 67% -- Rate orig new orig 21739/s -- -4% new 22727/s 5% -- # first run is valid arg, second is broken arg # new code is optimized for valid args *** strict1 Rate orig new orig 26316/s -- -38% new 42553/s 62% -- Rate orig new orig 19048/s -- -12% new 21739/s 14% -- *** subs3 Rate orig new orig 25641/s -- -40% new 42553/s 66% -- *** unknown1 Rate orig new orig 18018/s -- -19% new 22222/s 23% -- *** r1 Rate orig new orig 6061/s -- -36% new 9434/s 56% -- *** real_life2 Rate orig new orig 5848/s -- -37% new 9259/s 58% -- # first run is valid arg, second is broken arg # new code is optimized for valid args *** define1 Rate orig new orig 27778/s -- -39% new 45455/s 64% -- Rate orig new orig 21053/s -- -14% new 24390/s 16% -- *** real_life Rate orig new orig 6993/s -- -14% new 8130/s 16% -- *** invalid_store Rate orig new orig 43103/s -- -34% new 64935/s 51% -- # they are all failing test, so not that much diff *** invalid_key_tests Rate orig new orig 14493/s -- -16% new 17241/s 19% -- Rate orig new orig 14493/s -- -12% new 16393/s 13% -- Rate orig new orig 14085/s -- -13% new 16129/s 15% -- Rate orig new orig 13699/s -- -12% new 15625/s 14% -- # last case is broken arg # new code is optimized for valid args *** default Rate orig new orig 38961/s -- -36% new 61224/s 57% -- Rate orig new orig 29412/s -- -40% new 49180/s 67% -- Rate orig new orig 28302/s -- -24% new 37037/s 31% -- Rate orig new orig 15873/s -- -14% new 18519/s 17% -- *** big_template Rate orig new orig 5348/s -- -22% new 6897/s 29% -- # Huge gain here, with ALLOW_UNKNOWN = 1 *** unknown2 Rate orig new orig 35088/s -- -47% new 66667/s 90% -- *** store1 Rate orig new orig 28571/s -- -11% new 32258/s 13% -- *** simple Rate orig new orig 30612/s -- -38% new 49180/s 61% -- *** r2 Rate orig new orig 5814/s -- -38% new 9346/s 61% -- *** preserver_case1 Rate orig new orig 32258/s -- -31% new 46512/s 44% -- # first run is valid arg, second is broken arg # new code is optimized for valid args *** define2 Rate orig new orig 28571/s -- -39% new 46512/s 63% -- Rate orig new orig 21739/s -- -14% new 25316/s 16% -- *** subs2 Rate orig new orig 25316/s -- -38% new 40816/s 61% --
Subject: benchmark.pl
Download benchmark.pl
text/x-perl 10k
#!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese); use lib qw(/home/dams/scratchpad/Params-Check-0.26/lib); use Params::Check; use Params::Check2; my %tests = ( real_life => { count => 10000, code_in_func => 'my $foo1; my $foo2; my $foo3', template => q({ arg1 => { defined => 1, strict_type => 1, default => '' }, arg2 => { default => 'bar', store => \$foo1 }, arg3 => { default => 'mod', store => \$foo2 }, arg4 => { defined => 1, strict_type => 1, default => [], store => \$foo3 }, arg5 => { default => {}, strict_type => 1 }, arg6 => { default => 'a', allow => [ qw(b a c d) ], strict_type => 1}, }), params => [q({ arg1 => 'foo', arg2 => 'moz', arg4 => [ 'answer', 42 ], arg5 => { answer => 42 }, arg6 => 'c', })], }, real_life2 => { count => 10000, code => '$Params::Check::PRESERVE_CASE= 0; $Params::Check::ALLOW_UNKNOWN = 1; $Params::Check::SANITY_CHECK_TEMPLATE = 0; ', template => q({ arg1 => { defined => 1, strict_type => 1, default => ''}, arg2 => { default => 'bar'}, arg3 => { default => 'mod'}, arg4 => { defined => 1, strict_type => 1, default => ''}, arg5 => { default => 'bar'}, arg6 => { default => 'mod'}, arg7 => { defined => 1, strict_type => 1, default => ''}, arg8 => { default => 'bar'}, arg9 => { default => 'mod'}, }), params => [q({ arg1 => 'foo', arg2 => 'moz', arg3 => 'answer', arg4 => 'foo', arg5 => 'moz', arg6 => 'answer', arg7 => 'foo', arg8 => 'moz', arg9 => 'answer', })], }, r1 => { count => 10000, template => q({ arg1 => { defined => 1, strict_type => 1, default => ''}, arg2 => { default => 'bar'}, arg3 => { default => 'mod'}, arg4 => { defined => 1, strict_type => 1, default => ''}, arg5 => { default => 'bar'}, arg6 => { default => 'mod'}, arg7 => { defined => 1, strict_type => 1, default => ''}, arg8 => { default => 'bar'}, arg9 => { default => 'mod'}, }), params => [q({ arg1 => 'foo', arg2 => 'moz', arg3 => 'answer', arg4 => 'foo', arg5 => 'moz', arg6 => 'answer', arg7 => 'foo', arg8 => 'moz', arg9 => 'answer', })], }, r2 => { count => 10000, code => '$Params::Check::SANITY_CHECK_TEMPLATE = 0; ', template => q({ arg1 => { defined => 1, strict_type => 1, default => ''}, arg2 => { default => 'bar'}, arg3 => { default => 'mod'}, arg4 => { defined => 1, strict_type => 1, default => ''}, arg5 => { default => 'bar'}, arg6 => { default => 'mod'}, arg7 => { defined => 1, strict_type => 1, default => ''}, arg8 => { default => 'bar'}, arg9 => { default => 'mod'}, }), params => [q({ arg1 => 'foo', arg2 => 'moz', arg3 => 'answer', arg4 => 'foo', arg5 => 'moz', arg6 => 'answer', arg7 => 'foo', arg8 => 'moz', arg9 => 'answer', })], }, simple => { count => 30000, template => '{ arg1 => {}, }', params => ['{ arg1 => 1, }'], }, default => { count => 30000, template => '{ foo => { default => 1 } }', params => [ '{}', '{ foo => 2}', '{ FOO => 2}', '{ -foo => 2}', ], }, no_override => { count => 10000, template => '{ foo => { no_override => 1, default => 42 } }', params => [ '{ foo => 13 }', ], }, required => { count => 20000, template => '{ foo => { required => 1 } }', params => [ '{ foo => 42 }', '{ }', ], }, invalid_key_tests => { count => 10000, template => '{ foo => { allow => sub { 0 } } }', params => [ '{ foo => 1 }', '{ foo => "foo" }', '{ foo => [] }', '{ foo => bless({},__PACKAGE__) }', ], }, invalid_store => { count => 50000, template => q({ foo => { store => '' } }), params => [ '{ }', ], }, edge_case => { count => 30000, template => q({ foo => { default => '' } }), params => [ '{ }', ], }, big_template => { count => 10000, template => q({ firstname => { required => 1, defined => 1 }, lastname => { required => 1, store => \$lastname }, gender => { required => 1, allow => [qr/M/i, qr/F/i], }, married => { allow => [0,1] }, age => { default => 21, allow => qr/^\d+$/, }, id_list => { default => [], strict_type => 1 }, phone => { allow => sub { 1 if +shift } }, bureau => { default => 'NSA', no_override => 1 }, }), params => [ q({ firstname => 'joe', lastname => 'jackson', gender => 'M', married => 1, age => 21, id_list => [1..3], phone => '555-8844', }), ], }, preserver_case1 => { count => 20000, code => '$Params::Check::PRESERVE_CASE = 1', template => q({ Foo => { default => 1 } }), params => [ '{ Foo => 42 }', ], }, preserver_case2 => { count => 20000, code => '$Params::Check::PRESERVE_CASE = 0', template => q({ Foo => { default => 1 } }), params => [ '{ Foo => 42 }', ], }, unknown1 => { count => 20000, template => q({ }), params => [ '{ foo => 42 }', ], }, unknown2 => { count => 20000, code => '$Params::Check::ALLOW_UNKNOWN = 1', template => q({ }), params => [ '{ foo => 42 }', ], }, store1 => { count => 20000, code => '$Params::Check::NO_DUPLICATES = 1; my $foo;', template => q({ foo => { store => \$foo } }), params => [ '{ foo => 42 }', ], }, store2 => { count => 20000, code => '$Params::Check::NO_DUPLICATES = 0; my $foo;', template => q({ foo => { store => \$foo } }), params => [ '{ foo => 42 }', ], }, strict1 => { count => 20000, code => '$Params::Check::STRICT_TYPE = 0', template => q({ foo => { strict_type => 1, default => [] } }), params => [ '{ foo => [] }', '{ foo => {} }', ], }, strict2 => { count => 20000, code => '$Params::Check::STRICT_TYPE = 1', template => q({ foo => { default => [] } }), params => [ '{ foo => [] }', '{ foo => {} }', ], }, define1 => { count => 20000, code => '$Params::Check::ONLY_ALLOW_DEFINED = 0', template => q({ foo => { defined => 1, default => 1 } }), params => [ '{ foo => 42 }', '{ foo => undef }', ], }, define2 => { count => 20000, code => '$Params::Check::ONLY_ALLOW_DEFINED = 1', template => q({ foo => { default => 1 } }), params => [ '{ foo => 42 }', '{ foo => undef }', ], }, subs1 => { count => 20000, template => q({ foo => { allow => sub { [] } } }), params => [ '{ foo => [] }', ], }, subs2 => { count => 20000, template => q({ foo => { allow => sub { {} } } }), params => [ '{ foo => {} }', ], }, subs3 => { count => 20000, template => q({ foo => { allow => sub { 1 } } }), params => [ '{ foo => 1 }', ], }, ); #my @keep = qw(store1 store2); #my @keep = qw(r1 r2); #my @keep = qw(real_life real_life2); #if (@keep) { # my %f; # @f{@keep} = @tests{@keep}; # %tests = %f; #} while (my ($name, $data) = each(%tests)) { my ($count, $template, $params, $code, $code_in_func) = @{$data}{qw(count template params code code_in_func)}; local $Params::Check::VERBOSE; local $Params::Check::NO_DUPLICATES; local $Params::Check::STRIP_LEADING_DASHES; local $Params::Check::STRICT_TYPE; local $Params::Check::ALLOW_UNKNOWN; local $Params::Check::PRESERVE_CASE; local $Params::Check::ONLY_ALLOW_DEFINED; local $Params::Check::SANITY_CHECK_TEMPLATE; local $Params::Check::WARNINGS_FATAL; local $Params::Check::CALLER_DEPTH; local $Params::Check2::VERBOSE; local $Params::Check2::NO_DUPLICATES; local $Params::Check2::STRIP_LEADING_DASHES; local $Params::Check2::STRICT_TYPE; local $Params::Check2::ALLOW_UNKNOWN; local $Params::Check2::PRESERVE_CASE; local $Params::Check2::ONLY_ALLOW_DEFINED; local $Params::Check2::SANITY_CHECK_TEMPLATE; local $Params::Check2::WARNINGS_FATAL; local $Params::Check2::CALLER_DEPTH; $code_in_func ||= ''; $code ||= ''; my $code_original = $code; my $code_new = $code; my $code_new3 = $code; $code_new =~ s/Check/Check2/g; $code_new3 =~ s/Check/Check3/g; print "*** $name\n"; my $i = 0; foreach (@$params) { local $SIG{__WARN__} = sub {}; cmpthese($count, { orig => qq( $code_original; foo($_); sub foo { $code_in_func; Params::Check::check($template, \$_[0]) } ), new => qq( $code_new; foo($_); sub foo { $code_in_func; Params::Check2::check($template, \$_[0]) } ), }); } print "\n"; }
Subject: faster_reimpl.patch
Download faster_reimpl.patch
text/x-diff 17.5k

Message body is not shown because it is too large.

Subject: Check.pm
Download Check.pm
text/x-perl 20.8k

Message body is not shown because it is too large.

Download (untitled) / with headers
text/plain 406b
On Wed May 16 15:22:21 2007, DAMS wrote: Show quoted text
> Hi, > > I've worked on a reimplementation of this module for use in my company. > Here is the version I ended with, that is backward compatible, contains > the existing features, add 1 new feature, has the same code size, but is > (sometimes really) faster.
Thanks for the patch -- allow me some time to take a look at it and i'll get back to you. Cheers, Jos


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.