4

Libという名前のフォルダーがあり、File :: Findモジュールを使用して、ディレクトリ全体でそのフォルダーを検索していますD:\。ドライブに多くのサブディレクトリがある場合は、検索に長い時間がかかります。たとえば、5分でもかかります。そのLibをより速く検索して、数秒で実行できるようにするにはどうすればよいですか?

私のコードは次のようになります。

    find( \&Lib_files, $dir);
    sub Lib_files
    {
       return unless -d;
      if ($_=~m/^([L|l]ib(.*))/)
      {
          print"$_";
      }
      return;
    }
4

2 に答える 2

21

既存のインデックスなしでファイルシステムを検索することは、IOバウンドです。locateそうしないと、Windowsデスクトップ検索に至るまでの製品が存在しません。

D:\> dir /b/s > directory.lstそのコマンドの実行にかかる時間を入力して観察します。最初にファイルにインデックスを付けることなしにそれを打ち負かすことを期待するべきではありません。

できる大きな改善点の1つは、印刷の頻度を減らすことです。マイナーな改善点は、キャプチャする予定がない場合は、キャプチャ括弧を使用しないことです。

my @dirs;

sub Lib_files {
   return unless -d $File::Find::name; 
   if ( /^[Ll]ib/ ) {
        push @dirs, $File::Find::name;
   }
   return;
}

File::Find私のシステムでは、ホームディレクトリの下にあるすべてのサブディレクトリの名前を約150,000ファイルで印刷するために使用する単純なスクリプトは、実行に数分かかりますdir %HOME% /ad/b/s > dir.lst。これに対して、約20秒で完了します。

私は使用する傾向があります:

use File::Basename;

my @dirs = grep { fileparse($_) =~ /^[Ll]ib/ }
           split /\n/,  `dir %HOME% /ad/b/s`;

私のシステムでは15秒以内に完了しました。

dir.exeに他の何かがある可能性がある場合%PATH%cmd.exeのビルトインdirは呼び出されません。を使用qx! cmd.exe /c dir %HOME% /ad/b/s !して、権利dirが呼び出されていることを確認できます。

于 2009-11-23T15:02:24.983 に答える
-1

File::Findモジュールを使用しないのはどうですか

use Cwd;
sub find{
    my ($wdir) = shift;
    my ($sdir) = &cwd; 
    chdir($wdir) or die "Unable to enter dir $wdir:$!\n";
    opendir(DIR, ".") or die "Unable to open $wdir:$!\n";
    foreach my $name (readdir(DIR) ){
        next if ($name eq ".");
        next if ($name eq "..");
        if (-d $name){
            &find($name);
            next;
        }

        print $name ."\n";
        chdir($sdir) or die "Unable to change to dir $sdir:$!\n";
    }
    closedir(DIR);
}
&find(".");
于 2009-11-24T03:10:08.103 に答える