I agree with Brian and depesz: from a practical point of view, this function probably cannot start if you are trying to improve the performance of your application. However, you can write a much faster function commify. One way is to avoid regular expressions.
use strict;
use warnings;
use Benchmark qw(cmpthese);
sub commify_regex {
my $text = reverse $_[0];
$text =~ s{(\d\d\d)(?=\d)(?!\d*\.)}{$1,}g;
return scalar reverse $text;
}
sub commify_substr {
my $v = $_[0];
my $len = length $v;
my $dec = index($v, '.');
my $i = 3 + ($dec < 0 ? 0 : $len - $dec);
$len -- unless $v == abs($v);
while ($i < $len ++){
substr($v, -$i, 0, ',');
$i += 4;
}
return $v;
}
my @tests = qw(
1 12 123 1234 12345 123456 1234567
12345678 123456789 1234567890 12345678901
123456789012 1234567890123
);
push @tests, map "$_.$_", @tests;
push @tests, map - $_, @tests;
for my $t (@tests){
print "Incorrect for: ", $t, "\n"
unless commify_substr($t) eq commify_regex($t);
}
cmpthese( -2, {
regex => sub { commify_regex($_) for @tests },
substr => sub { commify_substr($_) for @tests },
});
Rate regex substr
regex 3277/s -- -54%
substr 7109/s 117% --
source
share