我正在编写一个日志解析器,它逐行读取日志,我有大约100个规则,它的工作原理如下:
if ($line =~ /blabla (field1) (field2)/)
{ do something }
else if ($line =~ /something (field1) (field2) else/)
{ do something }
但是对于一个大的日志文件,将一行与这么多规则匹配可能会很慢,它可能是O(n)
。
那么,对这个问题有什么建议吗?由于它不仅仅是普通的字符串和通配符匹配,我不知道是否有任何我可以使用的数据结构。
答案 0 :(得分:7)
也许可以使用调度表?
my %handlers = (
blabla => \&blabla,
something => \&something,
);
while (<>) {
my ($keyword) = $line =~ /^(\S+)/
or next;
$handlers{$keyword}
or next;
$handlers{$keyword}->($line);
}
答案 1 :(得分:5)
我相信你的优化还为时过早。
您是否尝试过这个名义上的大日志文件?它真的太慢了吗?然后,如果实际 太慢,请使用像Devel :: NYTProf这样的分析工具来找出究竟什么是慢的。
答案 2 :(得分:1)
我建议你重新设计你的日志解析器。可能是我错了,但我认为你试图匹配日志文件中可能出现的所有情况。
尝试使用词法和句法分析器。对不起,我不知道Perl上的好样本,但有Parse::Yapp
之类的内容答案 3 :(得分:1)
您可以使用Regexp::Assemble
将多个正则表达式合并为一个正则表达式以加快匹配速度以下是模块的描述
Regexp :: Assemble接受任意数量的正则表达式,并将它们组合成一个正则表达式(或RE),匹配单个RE匹配的所有表达式。
因此,只需要针对一个表达式测试目标字符串,而不是使用大型表达式列表进行循环。当你有几千种模式需要处理时,这很有趣。尽最大努力产生尽可能小的图案。
还可以跟踪原始模式,以便您可以确定形成组合模式的源模式中哪个是导致匹配发生的模式。