我有一个触发多个进程的应用程序。每个进程都会加载一个HTML文件并尝试查找是否出现模式,如下所示:
OUTER:
while(my ($prov,$arr_ref) = each(%{$self->{TAGS}})) {
foreach my $tag (@{$arr_ref}) {
if ($html =~ m/\Q$tag\E/i) {
$provider = $prov;
last OUTER;
}
}
}
$self->{TAGS}
键是一个模式名称,该值是对带有字符串(标量)的数组的引用。
我正在分析该程序,并发现这一部分:
$html =~ m/\Q$tag\E/i
让我的CPU跳到100%。如果我删除它,它几乎不会达到10%。
我只考虑了一种方法,即将每个数组ref中的所有标量(字符串)转换为已编译的正则表达式(qr/.../
)。我想这不会有太大的改进,因为我猜这个问题实际上当正则表达式实际上搜索所有HTML页面时,可能是几百个字节。
如何改善此部分?
SUB-QUESTION:由于下面的答案,以及我做的一些测试,我会提出我的问题,问题不是正则表达式,我之前已尝试index
方式我问过这个问题,还尝试使用qr//
编译正则表达式,这个问题是,对于html文件的大小,$html
内容是HTML文本,有时它很小,有时它很大,所以这里的问题是:什么是最好的方法(资源明智...)如果一个字符串出现在更大的内容(让我们说大小为1MB)?是什么?
感谢。
答案 0 :(得分:4)
使用index
可以提高性能,因为您将摆脱使用正则表达式的所有开销。请做一个基准!
$html_searchable = lc ($html);
...
while ( ... ) {
foreach ( ... ) {
if (index ($html_searchable, lc ($tag)) > -1) {
... # we got a match
}
}
}
如果您想进一步增加它,则应将所有$tag
存储为小写字符串,这样就不必多次lc
相同的字符串。
<强>文档强>
答案 1 :(得分:4)
\ Q表示您的正则表达式可以替换为index。对于与案例无关的搜索,$ html和$ tag应尽可能早地转换为小写。
my $htmllc=lc($html);
while () {
...
if (index($htmllc,$tag)>-1) {
...
}
}
P.S。您应该尝试对几种解决方案进行基准测试。