Joe Discenza wrote:

> Chris Wagner wrote, on Thu 6/30/2005 14:41
> 
> : At 12:16 PM 6/30/05 -0500, Joe Discenza wrote:
> : >I bet you're right that "eval($var) eq $var + 0" works; have you
> : >benchmarked it against all the other (regex, e.g.) methods presented?
> :
> : I haven't benchmarked it but I can garuntee that it's faster than a regex.
> : Anything's faster than that. ;)  This should cover everything:
> 
> Thanks for playing. I compared your function with a regex I whipped up
> (/^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$/, which gave the same
> results, except for distinguishing "pure" numbers, on your dataset):
> 
> Benchmark: timing 100000 iterations of chris, regex...
>      chris: 12 wallclock secs (11.86 usr +  0.00 sys = 11.86 CPU) @
> 8432.41/s (n=100000)
>      regex:  2 wallclock secs ( 1.56 usr +  0.00 sys =  1.56 CPU) @
> 63979.53/s (n=100000)
> 
> Regex is pretty fast. Eval is usually pretty slow.

1) I don't consider Chris's solution to be a legit solution until it
doesn't issue any warnings or error messages.

2) I got these numbers from my test (strict/warnings turned off) :

          Rate     RE STRTOD     IF    LLN
RE      7530/s     --   -72%   -75%   -75%
STRTOD 26948/s   258%     --   -10%   -11%
IF     29782/s   295%    11%     --    -2%
LLN    30274/s   302%    12%     2%     --

looks_like_number seems to be the winner.

I used the same two lines of code in each sub to clean up
the input:
        $var =~ s/^\s+//; $var =~ s/\s+$//;
        return 0 if not defined $var or $var eq '';

use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
use POSIX qw(strtod);
use Benchmark qw(timethese cmpthese);

# test output of subs before benchmarking

foreach my $sub (\&sub1, \&sub2, \&sub3, \&sub4) {

        foreach ("1e7", 0, 5, "6", "0.00", -4, "abc", "f4fc", '+.1', undef) {

                my $val = defined $_ ? $_ : 'undef';
                my $ret = &$sub ($_);
                print $ret ? "sub1 ($ret): '$val' is a number\n" :
                  "sub1 ($ret): '$val' is not a number\n";
                $ret = &$sub ($_);
                print $ret ? "sub2 ($ret): '$val' is a number\n" :
                  "sub2 ($ret): '$val' is not a number\n";
                $ret = &$sub ($_);
                print $ret ? "sub3 ($ret): '$val' is a number\n" :
                  "sub3 ($ret): '$val' is not a number\n";
                $ret = &$sub ($_);
                print $ret ? "sub4 ($ret): '$val' is a number\n" :
                  "sub4 ($ret): '$val' is not a number\n";
        }
}

no warnings;    # needed for Chris solution
no strict;      # needed for Chris solution

my $count = 1000000;
cmpthese ($count, {
                    RE => 'main (\&sub1)',
                    IF => 'main (\&sub2)',
                    STRTOD => 'main (\&sub3)',
                    LLN => 'main (\&sub4)',
                  });

sub main {
        my $cref = shift;

foreach ("1e7", 0, 5, "6", "0.00", -4, "abc", "f4fc", '+.1', undef) {
        &$cref ($_);
}

}

sub sub1 {
        my $var = shift;

$var =~ s/^\s+//; $var =~ s/\s+$//;
return 0 if not defined $var or $var eq '';

if ($var eq $var + 0) {
        return 1;
} elsif (eval $var eq $var + 0) {
        return 2;
}
return 0;

}

sub sub2 {
        my $var = shift;

$var =~ s/^\s+//; $var =~ s/\s+$//;
return 0 if not defined $var or $var eq '';

return 1 if $var =~ /^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$/;
return 0;

}

sub sub3 {
        my $var = shift;

$var =~ s/^\s+//; $var =~ s/\s+$//;
return 0 if not defined $var or $var eq '';

$! = 0;
my ($num, $unparsed) = strtod ($var);
return 0 if $unparsed or $!;
return 1;

}

sub sub4 {
        my $var = shift;

$var =~ s/^\s+//; $var =~ s/\s+$//;
return 0 if not defined $var or $var eq '';

# return looks_like_number ($var);
# code stripped from LLN:

return 1 if (/^[+-]?\d+$/); # is a +/- integer
return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or
  ($] >= 5.006001 and /^Inf$/i);

}

__END__


-- 
  ,-/-  __      _  _         $Bill Luebkert    Mailto:[EMAIL PROTECTED]
 (_/   /  )    // //       DBE Collectibles    Mailto:[EMAIL PROTECTED]
  / ) /--<  o // //      Castle of Medieval Myth & Magic http://www.todbe.com/
-/-' /___/_<_</_</_    http://dbecoll.tripod.com/ (My Perl/Lakers stuff)
_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to