Perl:替换变量时 s/// 的速度

Ole*_*nge 7 perl

这:

while($read=sysread(STDIN,$buf,32760)) {
    $buf=~s/\r/posttag\rpretag\t/go;
    $buf=~s/\n/posttag\npretag\t/go;
    syswrite(STDOUT,$buf);
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上传输约 200 MB/s。

这:

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);
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上传输约 100 MB/s。

为什么?

我认为当我使用时,/o内容是变量还是固定字符串应该没有关系。有没有一种简单的方法可以达到第一个的速度?

小智 7

您确定是正则表达式重新编译造成的吗?您可以使用以下命令获取有关 perl 对正则表达式执行的操作的信息

use re 'debug';
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,您在 s//HERE/ 中引入插值字符串,并且 perl 在每次迭代时对其进行插值。

尝试重写像

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);
}
Run Code Online (Sandbox Code Playgroud)


小智 6

根据该标志的perlop 文档/o,添加了重点:

“s/模式/替换/msixpodualngcer”

如果您希望仅在第一次插入变量时编译一次模式,请使用“/o”选项。

因此/o仅与模式相关,与替换无关。即使如此,一些程序员仍然认为/o这是一个问题,并且不会使用它,典型的情绪如下:

< pragma-> perlre#Modifiers: o - 假装优化你的代码,但实际上引入了错误

如果我必须提前插入右侧或替换,我可能会使用Sub::Quote或类似的方法将 RHS 转换为静态字符串。