Actually, $string =~ s/^\s+//;$string =~ s/\s+$//; is faster, matching only when there is one or more whitespace characters.
Your Benchmark is flawed and only strips whitespace on the very first run - $string is global.
Try this benchmark instead:
#!/usr/bin/perl
use warnings;
use strict;
use Benchmark qw(cmpthese timethese);
sub double_star {
my $string = shift;
$string =~ s/^\s*//;
$string =~ s/\s*$//;
return $string;
}
sub double_plus {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
sub replace {
my $string = shift;
$string =~ s/^\s*(\S*(?:\s+\S+)*)\s*$/$1/;
return $string;
}
sub for_star {
my $string = shift;
for ($string) { s/^\s+//; s/\s+$//; }
return $string;
}
sub for_plus {
my $string = shift;
for ($string) { s/^\s*//; s/\s*$//; }
return $string;
}
sub regex_or {
my $string = shift;
$string =~ s/(?:^ +)||(?: +$)//g;
return $string;
}
cmpthese(
-1,
{
'double_star' => q|double_star(' Mary had a little lamb. ');|,
'double_plus' => q|double_plus(' Mary had a little lamb. ');|,
'replace' => q|replace( ' Mary had a little lamb. ');|,
'for_star' => q|for_star( ' Mary had a little lamb. ');|,
'for_plus' => q|for_plus( ' Mary had a little lamb. ');|,
'regex_or' => q|regex_or( ' Mary had a little lamb. ');|,
}
);
Results:
Rate regex_or replace for_plus double_star for_star double_plus
regex_or 55855/s -- -47% -49% -60% -73% -84%
replace 105217/s 88% -- -5% -25% -49% -70%
for_star 110277/s 97% 5% -- -22% -46% -68%
double_star 140894/s 152% 34% 28% -- -31% -59%
for_plus 204799/s 267% 95% 86% 45% -- -41%
double_plus 345717/s 519% 229% 213% 145% 69% --