perl - 如何优化这个 Perl 文件查找?

标签 perl file-find

需求:获取输入目录下符合以下条件的目录数

  1. 目录可以使用除“DIR1”、“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; 
}

这段代码给出了所需的输出,但需要相当多的时间。

请提出改进​​此代码以减少所用时间的方法。

最佳答案

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)。对子目录进行分组,以便它们的子计数大致平衡,并在这些组上并行运行类似上述的内容。增益将取决于您的硬件,但应该有一个良好的加速系数。

关于perl - 如何优化这个 Perl 文件查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43994927/

相关文章:

windows - perl if( -e "带空格路径的窗口){}

HTML::TableExtract 的 Java 等效项

Perl File::Find: 先列出目录中的所有文件然后跳转到下一个目录?

perl 脚本递归列出目录中的所有文件名

performance - 如何使 Perl 的 File::Find 更快?

perl - 如何传递存储在变量中的xpath?

perl - coderefs 中的变量范围如果 perl,需要解释奇怪的行为

c++ - 制作 map 编辑器的语言/GUI库

perl - 使用 Perl 的 File::Find 时,如何将参数传递给想要的函数?

perl - File::Find::Rule 和文件分隔符