[Namazu-devel-ja 807] Re: File::MMagic::checktype_data

Yukio USUDA m6694ha392t @ asahi-net.or.jp
2005年 12月 27日 (火) 00:37:48 JST


臼田です。

Tadamasa Teranishi wrote:

> 「最後にマッチした部分がファイル先頭に近い部分のものを採用」という
> ことではないですし、「パターンにマッチした回数が多いものを採用」
> というわけではないので、
> 
> +               while ($data =~ /$token/mg) {
> +                   $count++;
> +               }
> 
> ループを回さず、最初に見つけたところの pos を記憶して、
> もっとも小さな値を採用すれば、より高速で現在と互換性のある
> ものができるでしょう。

現在の判定条件がよいのかどうかは別として
判定の互換性を考慮して File::MMagic::checktype_data の修正案を
もう一つ作成してみました。
前回の修正案と同様に処理時間は元の 1/18 程度と大幅に短くなります。
(前回のループを回すものより少し遅いかもしれません。)

$ diff -u MMagic.pm.org MMagic.pm
--- MMagic.pm.org       2005-08-28 00:20:31.000000000 +0900
+++ MMagic.pm   2005-12-27 00:13:43.000000000 +0900
@@ -678,17 +678,21 @@
     {
        # in BSD's version, there's an effort to search from
        # more specific to less, but I don't do that.
-       my ($token, %val);
+       my %val;
        foreach my $type (keys %{$self->{SPECIALS}}) {
-           my $token = '(' . 
-             (join '|', sort {length($a) <=> length($b)} @{$self->{SPECIALS}->{$type}})
-               . ')';
-           my $tdata = $data;
-           if ($tdata =~ /$token/mg) {
-               $val{$type} = pos($tdata);
-           }
-       }
 
+           my $matched_pos = undef;
+           foreach my $token (@{$self->{SPECIALS}->{$type}}){
+               pos($data) = 0;
+                if ($data =~ /$token/mg) {
+                   my $tmp =  pos($data);
+                   if ((! defined $matched_pos) || ($matched_pos > $tmp)) {
+                       $matched_pos = $tmp;
+                   }
+               }
+           }
+           $val{$type} = $matched_pos if $matched_pos;
+        }
        # search latest match
        if (%val) {
            my @skeys = sort { $val{$a} <=> $val{$b} } keys %val;


臼田幸生




Namazu-devel-ja メーリングリストの案内