3

ログを行ごとに読み取るログパーサーを作成しています。約100のルールがあり、次のように機能します。

if ($line =~ /blabla (field1) (field2)/) 
{ do something } 
else if ($line =~ /something (field1) (field2) else/)
{ do something }

しかし、大きなログ ファイルの場合、非常に多くのルールに対して 1 行を照合するのが遅くなる可能性がありますO(n)

それで、この問題について何か提案はありますか?単純な文字列とワイルドカードの一致だけではないため、使用できるデータ構造があるかどうかはわかりません。

4

4 に答える 4

7

おそらくディスパッチテーブルを使用できますか?

my %handlers = (
   blabla    => \&blabla,
   something => \&something,
);

while (<>) {
   my ($keyword) = $line =~ /^(\S+)/
      or next;

   $handlers{$keyword}
      or next;

   $handlers{$keyword}->($line);
}
于 2012-11-22T06:20:46.193 に答える
5

あなたの最適化は時期尚早だと思います。

この概念的な大きなログ ファイルで試してみましたか? 実際には遅すぎますか?次に、実際にすぎる場合は、Devel::NYTProf などのプロファイリング ツールを使用して、正確に何が遅いのかを調べます。

于 2012-11-22T04:28:48.550 に答える
1

Regexp :: Assembleを使用すると、複数の正規表現を1つに組み合わせて、一致を高速化できます。

以下はモジュールの説明からです

Regexp :: Assembleは、任意の数の正規表現を受け取り、それらを1つの正規表現(またはRE)にアセンブルします。これは、個々のREが一致するすべてに一致します。

その結果、ループする式の大規模なリストを用意する代わりに、ターゲット文字列を1つの式に対してテストするだけで済みます。これは、処理するパターンが数千ある場合に興味深いものです。可能な限り最小のパターンを作成するために真剣な努力が払われています。

元のパターンを追跡することもできるので、組み立てられたパターンを形成するソースパターンの中で、一致が発生した原因はどれであるかを判断できます。

于 2012-11-22T09:54:29.373 に答える
1

ログ パーサーを再設計することをお勧めします。私が間違っているかもしれませんが、ログ ファイルで発生する可能性のあるすべてのケースを一致させようとしていると思います。

字句パーサーと構文パーサーを使用してみてください。申し訳ありませんが、Perl の良いサンプルはわかりませんが、Parse::Yappのようなものです。

于 2012-11-22T03:51:24.940 に答える