我正在解析一些大日志文件,并且有一些非常简单的字符串匹配,例如
if(m/Some String Pattern/o){
#Do something
}
看起来很简单,但事实上我所拥有的大多数比赛都可以对抗线的开头,但比赛将会“更长”,例如
if(m/^Initial static string that matches Some String Pattern/o){
#Do something
}
显然,这是一个更长的正则表达式,因此需要更多工作来匹配。但是我可以使用行锚的开头,这将允许表达式更快地作为失败的匹配被丢弃。
我的预感是后者会更有效率。任何人都可以支持我/击落我: - )
答案 0 :(得分:6)
我认为你会发现用^开始正则表达式肯定会更快,因为正则表达式引擎不需要查看字符串左边缘的任何进一步匹配。
当然,这是您可以轻松测试和测量的内容。做正则表达式匹配1000万次左右,测量需要多长时间,然后再使用不同的正则表达式再次尝试。
答案 1 :(得分:4)
线锚使其更快。我必须补充说,这里不需要// o修饰符,事实上它什么都不做。那是我的代码味道。
曾经有过有用的用法,但是这些日子是由qr //
提供的答案 2 :(得分:3)
RE的速度取决于两个因素,即RE本身和通过RE的数据。通常,没有回溯的锚定RE(开始或结束)将比其他更快。但是,如果您正在处理每行都为空的文件,则/^hello/
和/hello/
之间没有速度差异(至少如果RE引擎写得正确的话)。
但我遵循的规则是:衡量,不要猜测。
答案 3 :(得分:3)
我按照建议做了一些时间安排。这是我的应用程序的结果。它是整个应用程序,而不仅仅是正则表达式搜索。它扫描了60,000行。 11正则表达式平均短长度约为30个字符。较长但锚定的约为120。
Short
real 0m58.780s
user 0m54.940s
sys 0m0.790s
Long (anchored)
real 0m54.260s
user 0m53.630s
sys 0m0.490s
Long (not anchored)
real 0m54.705s
user 0m54.130s
sys 0m0.400s
因此锚定长字符串会稍快一些。虽然不是很多。看来,如果我的字符串更大,那可能是另一回事。
答案 4 :(得分:2)
使用use re debug
编译指示,您可以深入了解正则表达式引擎在Perl中的作用。记录在案here
查看Perl suggested performance techniques总是有帮助的,包括建议的计时方法。
如果我进行这个小测试:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my $target="aeiou";
my $str="lkdjflzdjfljdsflkjasdjf asldkfj lasdjf dslfj sldfj asld alskdfj lasd f";
my $str2=$str.$target;
timethese(10_000_000, {
'float' => sub {
die "no match" unless $str2=~m/$target/o;
},
'anchored' => sub {
die "no match" unless $str2=~m/^.*$target/o;
},
'prefixed' => sub {
die "no match" unless $str2=~m/^$str$target/o ;
},
});
我得到了输出:
Benchmark: timing 10000000 iterations of anchored, float, prefixed...
anchored: 4 wallclock secs ( 3.46 usr + 0.01 sys = 3.47 CPU) @ 2881844.38/s
float: 2 wallclock secs ( 1.87 usr + 0.00 sys = 1.87 CPU) @ 5347593.58/s
prefixed: 4 wallclock secs ( 3.05 usr + 0.01 sys = 3.06 CPU) @ 3267973.86/s
这导致了非锚定(浮动)版本更快的结论。但是,正则表达式和源代码可能会改变这种情况。 YMMV和测试测试...
答案 5 :(得分:1)
你是说你可以通过添加一个静态前缀来锚定正则表达式吗?
/^blah blah The Real Regex/
这肯定不会伤害性能,它可能会有所帮助,但不是因为你认为的原因。虽然他们最着名的是“神奇”的东西,比如锚点和外观以及捕获组,但正则表达式引擎最擅长的是匹配字符序列。序列越长,匹配越快(当然直到某一点)。
换句话说,它是添加静态前缀而不是锚点,它可以为你提供支持。
答案 6 :(得分:0)
我投票支持开头的那个,正是因为你陈述的原因!