This:
while($read=sysread(STDIN,$buf,32760)) {
$buf=~s/\r/posttag\rpretag\t/go;
$buf=~s/\n/posttag\npretag\t/go;
syswrite(STDOUT,$buf);
}
delivers ~200 MB/s on my system.
This:
my $pretag = "pretag";
my $posttag = "posttag";
while($read=sysread(STDIN,$buf,32760)) {
$buf=~s/\r/$posttag\r$pretag\t/go;
$buf=~s/\n/$posttag\n$pretag\t/go;
syswrite(STDOUT,$buf);
}
delivers ~100 MB/s on my system.
Why?
I thought that when I had used /o
it should not matter if the content is a variable or a fixed string. Is there an easy way I can get the speed of the first?
CodePudding user response:
Are you sure that regexp recompilation is to blame? You can get information about what perl is doing with your regexps using
use re 'debug';
In second case you introduce interpolated string in s//HERE/ and perl interpolates it with each iteration.
Try to rewrite like
my $pretag = 'pretag';
my $posttag = 'posttag';
my $first_replace = "$posttag\r$pretag\t";
my $second_replace = "$posttag\n$pretag\t";
while($read=sysread(STDIN,$buf,32760)) {
$buf=~s/\r/$first_replace/go;
$buf=~s/\n/$second_replace/go;
syswrite(STDOUT,$buf);
}
CodePudding user response:
Per the perlop
documentation for the /o
flag, emphasis added:
"s/PATTERN/REPLACEMENT/msixpodualngcer"
If you want the pattern compiled only once the first time the variable is interpolated, use the "/o" option.
Therefore /o
is only relevant to the pattern, not the replacement. Even then some programmers consider /o
to be a problem, and will not use it, with the typical sentiment running along the lines of:
< pragma-> perlre#Modifiers: o - pretend to optimize your code, but actually introduce bugs
If I had to interpolate the Right-Hand-Side or replacement in advance, I'd probably use Sub::Quote or similar to turn the RHS into static strings.