我正在遍历整个分区,stat()
'ing 每个文件,然后根据散列值检查返回的 mtime、size 和 uid 值。stat()
但是在 Perl 中速度太慢了,我想知道是否有更快的替代方案我可能会忽略。
6 回答
当您打电话时,stat
您正在查询文件系统,并且会受到其性能的限制。对于大量文件,这会很慢;这不是一个真正的 Perl 问题。
在开始优化stat之前,使用Devel::NYTProf查看真正的减速在哪里。
此外,调查您如何安装文件系统的详细信息。一切都是本地的,还是您通过 NFS 或类似的东西安装了一些东西?正如其他答案所指出的那样,有很多事情可能是问题所在。不要花太多时间关注任何潜在的问题,直到你知道这是问题所在。
祝你好运,
stat
正在对每个文件执行 IO,如果您想读取这些数据,这是无法避免的。所以这将是速度的限制,并且无法以我能想到的任何其他方式解决。
如果您重复stat
使用相同的文件,请考虑使用Memoize
.
use Memoize();
sub fileStat {
my ($filename) = @_;
return stat($filename);
}
Memoize::memoize('fileStat');
你已经看到它stat
已经足够慢了,所以不要在同一个文件上多次调用它。
-X (shell-ish 文件测试操作符)上的perlfunc 文档stat
描述了一个很好的缓存:
如果任何文件测试(或
stat
orlstat
运算符)被赋予由单独的下划线组成的特殊文件句柄,则使用前一个文件测试(或 stat 运算符)的 stat 结构,保存系统调用。(这不适用于-t
,您需要记住这一点lstat
,-l
并将值保留在符号链接的 stat 结构中,而不是真实文件中。)(另外,如果 stat 缓冲区被lstat
调用填充,-T
并将-B
重置它与stat _
)的结果。例子:print "Can do.\n" if -r $a || -w _ || -x _; stat($filename); print "Readable\n" if -r _; print "Writable\n" if -w _; print "Executable\n" if -x _; print "Setuid\n" if -u _; print "Setgid\n" if -g _; print "Sticky\n" if -k _; print "Text\n" if -T _; print "Binary\n" if -B _;
考虑File::Find模块。
- 如果你在 *NIX 上,你可以使用
ls
和解析输出,我想。 - 正如 Ether 所提到的,
find
如果您只想对自己的统计数据做出决定,那么它可能是一个不错的选择。 - 但是大小、日期和 uid 都应该可以从
ls
输出中获得。 - 而日期和大小可从
dir
Windows 平台上的命令获得。