2017-05-16 14 views
2

要件:ディレクトリは「DIR1」以外の任意の名前を付けることができこのPerlファイルを最適化する方法はありますか?

  1. 、次の条件に一致する入力ディレクトリの下にディレクトリの数を取得するには、「DIR2」、「DIR3」など
  2. ディレクトリ"DIR1"、 "DIR2"、 "DIR3" などの内側に
  3. だけではディレクトリの数を必要とする、なしファイル
use strict; 
use File::Find; 

my ($inputdir) = @ARGV; 
my (@branches, $branch, $directory, @directories); 
my $count = 0; 

find(\&wanted, $inputdir); 
    while (defined($directory = shift @directories)) { 
      if (-d $directory){ 
      next if ($directory =~ "DIR1" || $directory =~ "DIR2" || $directory =~ "DIR3"); 
        push @branches, $directory; 
        $count++; 
      } 
    } 

print "Total number of directories: $count \n"; 

sub wanted{ 
    push @directories, $File::Find::name; 
    return @directories; 
} 
をカウントする必要はありません

このコードは必要な出力を与えていますが、かなりの時間がかかります。

このコードを改善する時間を短縮する方法を提案してください。

+1

いくつのディレクトリがありますか? – simbabque

+2

私は、この問題をコードについて解説していますので、このトピックを閉じることに投票しています。https://codereview.stackexchange.com/ – Jens

+0

@simbabque約50万円 –

答えて

3

File::Find::Ruleは、全体の枝をスキップすることができ、完全に

use warnings; 
use strict; 

use File::Find::Rule; 

my $start_dir = shift || '.'; 

my $re_skip = qr/DIR(?:1|2|3)/; 

my $ok = File::Find::Rule->directory; # add selection rules as needed 
my $skip = File::Find::Rule->directory 
    ->name(qr/$re_skip/) 
    ->prune 
    ->discard; 

my @dirs = File::Find::Rule -> any($skip, $ok) -> in($start_dir); 

print "Total: ", scalar @dirs, "\n"; 

これはまだ大規模なファイルシステムでいくつかの時間を取るために持っていますが、それははるかに良いでしょう。ワンライナーで

、あなたはここから必要なのは、私がスクリプトからコードの一部を統合してきただけで、迅速、カウント

perl -MFile::Find::Rule -wE' 
    $ffr = File::Find::Rule; 
    $skip = $ffr->directory->name(qr/DIR(?:1|2|3)/)->prune->discard; 
    say scalar $ffr->any($skip, $ffr->directory)->in(".")' 

ある場合。

次のステップは、マルチスレッド実行を使用することです(ここではforkを使用します)。グループのサブディレクトリは、サブカウントがほぼ均等になるようにし、上記のようなものをそれらのグループに対して並行して実行します。ゲインはお使いのハードウェアによって異なりますが、スピードアップの面で優れているはずです。

+0

ありがとう@zdim! file-find-ruleを使うと時間が半分になりました。しかし、まだマルチスレッドを試みています。 –

+0

@kingそれはちょうどいいはずです。フォークされたコードが役立つかどうかを教えてください。追加することもできます。 – zdim

関連する問題