4

最初に、このような質問をされたことをお詫び申し上げます。ハッシュの配列と配列のハッシュを作成する方法を見つけることなく、答えを探すのは難しい....

ログアナライザーを作成しています。各エラー エントリの形式は次のとおりです。

timestamp # # human_timestamp errno #

次のことを行うために、マッピング関数を使用してハッシュのハッシュを作成しました。

$logRef->{++$errCnt} =
{
    line       => $lineNum,
    timestamp  => $timestamp,
    humanStamp => $humanStamp,
    errno      => $errno,
    text       => ''
};

後で、行番号間のエントリを分離したい分析を行います。分析エントリもハッシュに保存されます...

$analysis{++$iteration} =
{
    result    => $result,
    startLine => $startLine,
    endLine   => $endLine,
    errors    => undef
};

$analysis{errors} は配列参照になります。以下の操作で埋まります。

foreach my $iteration ( keys %analysis )
{
    my @errKeys = grep { $logRef->{$_}{line} >= $analysis{$iteration}{startLine} &&
                         $logRef->{$_}{line} <= $analysis{$iteration}{endLine} }
                  keys %$logRef;

    my @errs = ();
    push @errs, $logRef->{$_}{errno} foreach ( @errKeys );

    $analysis{$iteration}{errors} = \@errs;
}

ログ ファイルに 30000 以上のエントリが含まれることは珍しくありません。errs 配列の作成を除いて、分析はかなり迅速に実行されます。この配列を生成するより効率的な方法はありますか?

ありがとう

4

2 に答える 2

6

のようなことを言っていることに気付いたときはいつでも$hash{++$counter} = ...、配列 ( ) を使用する方が適切かどうかを自問してください$array[++$counter] = ...

ハッシュ要素を取得する$hash{$key}には、Perl がハッシュ関数を介してキーを渡し、リンクされたリストを走査して、値を見つけるために 1 つ以上の文字列比較を実行する必要があります。キーを文字列化するのにも多少の労力がかかる場合があります。

配列要素の検索ははるかに高速です。Perl はインデックスを数値に変換する必要があるかもしれませんが、そこから配列値を保持しているメモリ位置を見つけるのは簡単です。

于 2011-09-23T16:01:09.447 に答える
2

あなたはマイクロ最適化について質問しています。予測が難しい場合もあるため、ベンチマークが重要です。


ハッシュはリンクリストの配列です。それらは本質的に配列を使用するよりも遅くなるので、

$logRef->{++$errCnt} = ...;

より少し遅いです

push @$logRef, ...;

配列に変換し、他のいくつかのマイクロ最適化を行うと、次のことが可能になります。

foreach my $analysis ( @analysis )
{
    $analysis->{errors} = [
       map $_->{errno},
         grep $_->{line} >= $analysis->{startLine}
             && $_->{line} <= $analysis->{endLine},
           @$logRef
    ];
}

または多分さえ

foreach my $analysis ( @analysis )
{
    $analysis->{errors} = [
       map $_->{line} >= $analysis->{startLine}
           && $_->{line} <= $analysis->{endLine},
               ? $_->{errno}
               : (),
         @$logRef
    ];
}

なぜなら

  • grep EXPR,およびよりもmap EXPR,高速です。grep BLOCKmap BLOCK
  • 他のすべてが等しい場合、より少ない操作がより高速であるため、これにより不要な操作がカットされます。
于 2011-09-23T16:56:22.760 に答える