数値をカンマ区切りにするベンチマーク

需要ないと思いますが、perlで数値を3桁毎にカンマ区切りフォーマットに変換する
正規表現ベンチマークです。*1

スクリプト

#!/usr/bin/perl
use strict;
use warnings;
use Math::BigInt;
use Benchmark qw(timethese  cmpthese);

my $dbg = 0;

my $count = 100000;

my $comp = timethese(
    $count,
    {
        comma1_short => sub {comma1(1234);},
        comma2_short => sub {comma2(1234);},
        comma3_short => sub {comma3(1234);},
        comma4_short => sub {comma4(1234);},
        comma5_short => sub {comma5(1234);},
        comma1_long => sub {comma1(1234567890123456789);},
        comma2_long => sub {comma2(1234567890123456789);},
        comma3_long => sub {comma3(1234567890123456789);},
        comma4_long => sub {comma4(1234567890123456789);},
        comma5_long => sub {comma5(1234567890123456789);},
    }
);

cmpthese $comp;

# http://www.din.or.jp/~ohzaki/perl.htm#NumberWithComma
#
sub comma1 {
    my $price = shift;
    1 while $price =~ s/^([-+]?\d+)(\d\d\d)/$1,$2/;
    print "1:$price\n" if $dbg;
}

sub comma2 {
    my $price = shift;
    $price =~ s/(\d{1,3})(?=(?:\d\d\d)+(?!\d))/$1,/g;
    print "2:$price\n" if $dbg;
}
sub comma3 {
    my $price = shift;
    $price =~ s/\G((?:^[-+])?\d{1,3})(?=(?:\d\d\d)+(?!\d))/$1,/g;
    print "3:$price\n" if $dbg;
}
sub comma4 {
    my $price = shift;
    $price = reverse(join(',', reverse($price) =~ /((?:^\d+\.)?\d{1,3}[-+]?)/g))
      if $price =~ /^[-+]?\d\d\d\d/;
    print "4:$price\n" if $dbg;
}
sub comma5 {
    my $price = shift;
    my ($i,$j);
    if ($price =~ /^[-+]?\d\d\d\d+/g) {
        for ($i = pos($price) - 3, $j = $price =~ /^[-+]/; $i > $j; $i -= 3) {
            substr($price, $i, 0) = ',';
        }
    }
    print "5:$price\n" if $dbg;
}

結果

Benchmark: timing 100000 iterations of comma1_long, comma1_short, comma2_long, comma2_short, comma3_long, comma3_short, comma4_long, comma4_short, comma5_long, comma5_short...
comma1_long:  2 wallclock secs ( 2.12 usr +  0.00 sys =  2.12 CPU) @ 47169.81/s (n=100000)
comma1_short:  0 wallclock secs ( 0.49 usr +  0.00 sys =  0.49 CPU) @ 204081.63/s (n=100000)
comma2_long:  0 wallclock secs ( 1.34 usr +  0.01 sys =  1.35 CPU) @ 74074.07/s (n=100000)
comma2_short:  1 wallclock secs ( 0.58 usr +  0.00 sys =  0.58 CPU) @ 172413.79/s (n=100000)
comma3_long:  1 wallclock secs ( 1.31 usr +  0.00 sys =  1.31 CPU) @ 76335.88/s (n=100000)
comma3_short:  1 wallclock secs ( 0.53 usr +  0.01 sys =  0.54 CPU) @ 185185.19/s (n=100000)
comma4_long:  0 wallclock secs ( 0.81 usr +  0.00 sys =  0.81 CPU) @ 123456.79/s (n=100000)
comma4_short:  1 wallclock secs ( 0.37 usr +  0.00 sys =  0.37 CPU) @ 270270.27/s (n=100000)
            (warning: too few iterations for a reliable count)
comma5_long:  1 wallclock secs ( 0.72 usr +  0.00 sys =  0.72 CPU) @ 138888.89/s (n=100000)
comma5_short:  0 wallclock secs ( 0.43 usr +  0.00 sys =  0.43 CPU) @ 232558.14/s (n=100000)
                 Rate comma1_long comma2_long comma3_long comma4_long comma5_long comma2_short comma3_short comma1_short comma5_short comma4_short
comma1_long   47170/s          --        -36%        -38%        -62%        -66%         -73%         -75%         -77%         -80%         -83%
comma2_long   74074/s         57%          --         -3%        -40%        -47%         -57%         -60%         -64%         -68%         -73%
comma3_long   76336/s         62%          3%          --        -38%        -45%         -56%         -59%         -63%         -67%         -72%
comma4_long  123457/s        162%         67%         62%          --        -11%         -28%         -33%         -40%         -47%         -54%
comma5_long  138889/s        194%         87%         82%         12%          --         -19%         -25%         -32%         -40%         -49%
comma2_short 172414/s        266%        133%        126%         40%         24%           --          -7%         -16%         -26%         -36%
comma3_short 185185/s        293%        150%        143%         50%         33%           7%           --          -9%         -20%         -31%
comma1_short 204082/s        333%        176%        167%         65%         47%          18%          10%           --         -12%         -24%
comma5_short 232558/s        393%        214%        205%         88%         67%          35%          26%          14%           --         -14%
comma4_short 270270/s        473%        265%        254%        119%         95%          57%          46%          32%          16%           --

*1:cpanにありそうだけど