Home > perl, Programming, Tip > Yet another way to convert strings to numbers in Perl

Yet another way to convert strings to numbers in Perl

OK I know what you are gonna say when you see the title of this post — it’s not necessary to convert strings to numbers, strings are numbers if they look like numbers and Perl will treat them like numbers when you want it to. But there are some situations where data cleaning is required, for example, importing data from a csv file into database and you want to make sure numeric columns contains only numbers, strings such as ‘a345’, ‘ ‘, will be converted to 0 before they are being inserted into the database. For the past I’ve been using the following home-cooked method to do the conversion

sub tonum {
	return $_[0] =~ m/^\s*([+-]?\d+(\.\d+)?)\s*$/?$1:0;
}

This functions converts strings like ' +123.00', '78 ', '-333.456', '+abc' into '+123.00', '78', '-333.456', and '0' respectively. However I found yet another way to perform the same task and it’s much faster:

sub tonum2 {
	no warnings;
	return $_[0]+0;
}

How much faster can this method beat the previous one? I wrote a couple of testing scripts:

cat a.pl

#!/usr/bin/perl
use warnings;
use strict;

sub tonum {
	return $_[0] =~ m/^\s*([+-]?\d+(\.\d+)?)\s*$/?$1:0;
}
my $v;
for my $j (0..1_000_000) {
	for my $i (' 23.45', '-7  ', 'a34.56') {
		$v= tonum($i);
	}
}

———————————
time perl a.pl

real 0m31.250s
user 0m31.202s
sys 0m0.012s

cat b.pl

#!/usr/bin/perl
use warnings;
use strict;

sub tonum2 {
	no warnings;
	return $_[0]+0;
}
my $v;
for my $j (0..1_000_000) {
	for my $i (' 23.45', '-7  ', 'a34.56') {
		$v= tonum2($i);
	}
}

———————————
time perl b.pl

real 0m8.633s
user 0m8.617s
sys 0m0.008s

We now have our clear winner. The tricky part is tonum2 takes advantage of “no warnings” statement which suppresses the “Argument blahblah isn’t numeric” warnings. It’s kind of like the @ operator in PHP.

Advertisements
Categories: perl, Programming, Tip
  1. April 29, 2011 at 1:06 am

    Nonsense about not needing to convert strings to ints in perl/php. I convert strings to integers all the time to enforce data integrity and also to prevent sql injections and xss attacks where variables should only be numbers.

  2. ricoch3n
    April 29, 2011 at 1:17 am

    Chris, that’s exactly why I wrote this post. I am just curious, are you using the built-in int() to do the conversion? If so how do you turn off the warning when trying to do something like the following:

    int(‘abc’);

  3. October 14, 2016 at 3:16 pm

    Beware when adding zero to a string. If the string starts with “inf” or with “nan”, the value will not be zero.
    E.g.
    my $var2 = “info123”;
    print $var2 + 0:
    Result will be: Inf

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: