如何提高File :: Find :: Rule调用的性能?

Ale*_*lds 9 unix perl posix file find

File::Find::Rule用于在以下指定的目录中找到一级深度的用户可执行文件夹$dir:

my @subDirs = File::Find::Rule->permissions(isExecutable => 1, user => "$uid")->
                                extras({ follow => 1, follow_skip => 2 })->
                                directory->
                                maxdepth(1)->
                                in( $dir );
Run Code Online (Sandbox Code Playgroud)

这是使用UNIX find实用程序的粗略等效项:

my $subDirStr = `find $dir -maxdepth 1 -type d -user $username -perm -100`;
chomp($subDirStr); 
my @subDirs = split("\n", $subDirStr);
Run Code Online (Sandbox Code Playgroud)

两者都在具有恢复此数据权限的脚本中运行.

如果我find在命令行上运行语句,结果会立即返回.

如果我通过Perl脚本运行上述任一语句,结果需要几秒钟才能运行.

我可以通过编程方式来提高两种Perl方法中的任何一种的性能吗?

Gra*_*ean 5

我怀疑你看到的延迟是由于产生所有结果所需的时间长度.当然,如果你将find命令输入less,你会立即获得结果,但是如果你将其输入,tail你可能会看到类似于你在Perl脚本中看到的延迟.

在您的两个替代实现中,您正在创建一个包含所有匹配文件列表的数组 - 在文件匹配过程完成之前,您的代码将不会继续.

您也可以使用这样的迭代器方法:

my $rule = File::Find::Rule->permissions(isExecutable => 1, user => $uid)
                           ->extras({ follow => 1, follow_skip => 2 })
                           ->directory
                           ->maxdepth(1)
                           ->start($dir);
while( defined ( my $path = $rule->match ) ) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

为了完整性,您可以使用find命令获得类似的结果.您可以显式使用管道并一次读取一个结果,而不是使用反引号:

open my $pipe, 'find $dir -maxdepth 1 -type d -user $username -perm -100|' or die "Can't run find: $!";
while(my $path = <$pipe>) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,通过这两个示例,您的代码可以在找到第一个匹配项后立即开始处理结果.但是,处理最后一个结果所用的总时间与原始代码的差别不大.