Here's the benchmark. It seems changing the lengths of the involved strings heavily influences the results:
#!/usr/bin/perl
use warnings;
use strict;
use Test::More;
use Benchmark qw{ cmpthese };
sub regex {
my ($string, $find, $replace) = @_;
$string =~ s/\Q$find/$replace/g;
$string
}
sub substring {
my ($string, $find, $replace) = @_;
my $length = length $find;
my $pos = 0;
while (-1 != ( $pos = index $string, $find, $pos )) {
substr $string, $pos, $length, $replace;
}
$string
}
sub array {
my ($string, $find, $replace) = @_;
join $replace, split /\Q$find/, $string, -1
}
my @args = ('12a345a678a90', 'a', '||');
is regex(@args), '12||345||678||90', 'manual';
for my $args (\@args,
[ '123456789abcdefghijkl' x 1000,
'123456789abcdefghijkl' x 21,
'ABCDEFGH'
]) {
is regex(@$args), substring(@$args), 'regex - substring';
is substring(@$args), array(@$args), 'substring - array';
cmpthese(-3,
{ regex => sub { regex(@$args) },
substring => sub { substring(@$args) },
array => sub { array(@$args) },
});
}
done_testing(5);
Output on my machine (Perl 5.20.1, Linux on Intel i3):
ok 1 - manual
ok 2 - regex - substring
ok 3 - substring - array
Rate regex substring array
regex 313491/s -- -21% -36%
substring 398041/s 27% -- -19%
array 488419/s 56% 23% --
ok 4 - regex - substring
ok 5 - substring - array
Rate substring array regex
substring 18505/s -- -15% -15%
array 21765/s 18% -- -0%
regex 21765/s 18% 0% --
1..5
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
|