use strict;
use warnings;
use Benchmark qw(cmpthese);
my $x = "0123456789abcdefg" x 6000 . "XXX";
sub subst { my $s = $x; $s =~ s/(.{16})/$1 /sg; $s };
sub up { join ' ', unpack '(A16)*', $x }
sub m_substr {
my $s = $x;
for (my $i=16*int(length($s)/16);$i;$i-=16) {
substr($s,$i,0)=" ";
}
$s;
}
sub readline {
local $/ = \16;
my $s;
open my $handle, '<', \$x;
$s = <$handle>;
while (<$handle>) {
$s .= ' ' . $_;
}
$s;
}
my $ref = subst();
sub wrap {
my ($impl, $sub) = @_;
die "Wrong result for $impl!" unless $sub->() eq $ref;
}
cmpthese(-1, {
subst => wrap('subst', \&subst),
unpack => wrap('unpack',\&up),
substr => wrap('substr',\&m_substr),
readl => wrap('readline', \&readline),
})
####
Rate readl subst unpack substr
readl 78783885/s -- -17% -18% -24%
subst 95302528/s 21% -- -1% -8%
unpack 96105165/s 22% 1% -- -8%
substr 103929656/s 32% 9% 8% --
####
Rate subst readl substr unpack
subst 81695687/s -- -1% -36% -65%
readl 82899185/s 1% -- -35% -65%
substr 128382089/s 57% 55% -- -46%
unpack 235800076/s 189% 184% 84% --