#!/usr/bin/perl -w use Benchmark qw(timethese cmpthese countit timestr); use CGI::Ex::Dump qw(debug); use CGI::Ex::Validate; use Data::FormValidator; my $form = { username => "++foobar++", password => "123", password2 => "1234", }; my $val_hash_ce = { username => { required => 1, match => 'm/^\w+$/', match_error => '$name may only contain letters and numbers', untaint => 1, }, password => { required => 1, match => 'm/^[ -~]{6,30}$/', # min_len => 6, # max_len => 30, # match => 'm/^[ -~]+$/', untaint => 1, }, password2 => { validate_if => 'password was_valid', equals => 'password', }, email => { required => 1, match => 'm/^[\w\.\-]+\@[\w\.\-]+$/', untaint => 1, }, }; my $val_hash_df = { required => [qw(username password email)], dependencies => { password => [qw(password2)], }, constraints => { email => qr/^[\w\.\-]+\@[\w\.\-]+$/, password => qr/^[ -~]{6,30}$/, username => qr/^\w+$/, }, untaint_all_constraints => 1, msgs => { format => '%s', prefix => 'error_', }, }; sub check_form { my $form = shift; my $hash = {}; if (! exists $form->{'username'}) { push @{ $hash->{'username_error'} }, 'Username required'; } elsif ($form->{'username'} !~ m/^(\w+)$/) { push @{ $hash->{'username_error'} }, 'Username may only contain letters and numbers'; } else { $form->{'username'} = $1; } if (! exists $form->{'password'}) { push @{ $hash->{'password_error'} }, 'Password required'; } else { if ($form->{'password'} !~ m/^([ -~]+)$/) { push @{ $hash->{'password_error'} }, 'Password contained bad characters'; } else { $form->{'password'} = $1; } if (length($form->{'password'}) < 6) { push @{ $hash->{'password_error'} }, 'Password must be more than 6 characters'; } elsif (length($form->{'password'}) > 30) { push @{ $hash->{'password_error'} }, 'Password must be less than 30 characters'; } if (exists($form->{'password'}) && ! $hash->{'password_error'} && (! defined($form->{'password2'}) || $form->{'password2'} ne $form->{'password'})) { push @{ $hash->{'password2_error'} }, 'Password2 and password must be the same'; } } if (! exists $form->{'email'}) { push @{ $hash->{'email_error'} }, 'Email required'; } elsif ($form->{'email'} !~ m/^[\w\.\-]+\@[\w\.\-]+$/) { push @{ $hash->{'email_error'} }, 'Please type a valid email address'; } return $hash; } debug(CGI::Ex::Validate->validate($form, $val_hash_ce)->as_hash); debug(Data::FormValidator->check($form, $val_hash_df)->msgs); debug(check_form($form)); cmpthese (-2,{ cgi_ex => sub { my $t = CGI::Ex::Validate->validate($form, $val_hash_ce) }, data_val => sub { my $t = Data::FormValidator->check($form, $val_hash_df) }, homegrown => sub { my $t = check_form($form) }, },'auto'); cmpthese (-2,{ cgi_ex => sub { my $t = CGI::Ex::Validate->validate($form, $val_hash_ce)->as_hash }, data_val => sub { my $t = Data::FormValidator->check($form, $val_hash_df)->msgs }, homegrown => sub { my $t = scalar keys %{ check_form($form) } }, },'auto'); ### Home grown solution blows the others away - but lacks features # # Benchmark: running cgi_ex, data_val, homegrown for at least 2 CPU seconds... # cgi_ex: 3 wallclock secs ( 2.04 usr + 0.00 sys = 2.04 CPU) @ 2845.10/s (n=5804) # data_val: 3 wallclock secs ( 2.17 usr + 0.00 sys = 2.17 CPU) @ 1884.79/s (n=4090) # homegrown: 3 wallclock secs ( 2.13 usr + 0.00 sys = 2.13 CPU) @ 77093.43/s (n=164209) # Rate data_val cgi_ex homegrown # data_val 1885/s -- -34% -98% # cgi_ex 2845/s 51% -- -96% # homegrown 77093/s 3990% 2610% -- # Benchmark: running cgi_ex, data_val, homegrown for at least 2 CPU seconds... # cgi_ex: 2 wallclock secs ( 2.21 usr + 0.01 sys = 2.22 CPU) @ 2421.17/s (n=5375) # data_val: 2 wallclock secs ( 2.27 usr + 0.03 sys = 2.30 CPU) @ 1665.22/s (n=3830) # homegrown: 2 wallclock secs ( 2.04 usr + 0.01 sys = 2.05 CPU) @ 72820.00/s (n=149281) # Rate data_val cgi_ex homegrown # data_val 1665/s -- -31% -98% # cgi_ex 2421/s 45% -- -97% # homegrown 72820/s 4273% 2908% --