Perl one-liner到空目录解释

时间:2015-02-25 09:20:05

标签: perl

This article指出了一种用perl清空包含大文件的目录的方法:

perl -e 'for(<*>){((stat)[9]<(unlink))}'

它让我感到困惑,因为它调用stat并与每个文件的unlink的返回值进行比较。

我在没有打电话给stat的情况下进行了测试,而且单线程更快。在这里调用stat的目的是什么?

1 个答案:

答案 0 :(得分:3)

统计数据毫无用处,可能是对性能优化的一次尝试。

您可以通过B::Deparse运行它,看看它没有做任何有趣的事情。

$ perl -MO=Deparse -e 'for(<*>){((stat)[9]<(unlink))}'
use File::Glob ();
foreach $_ (<*>) {
    (stat $_)[9] < unlink($_);
}
-e syntax OK

(stat)[9]是自1970年以来的文件修改时间(以秒为单位),通常是一个很大的数字。 unlink返回已删除的文件数,在这种情况下,它总是为0或1.无论如何都没有检查该比较(添加-w和Perl会警告你)。

这将做同样的事情并且更快。

perl -e 'unlink for <*>'

我有两个猜测。首先是作者打算写(stat)[9] && unlink,它会在取消链接之前检查文件是否存在。 Apparently there's some voodoo about this sometimes being faster。这是不正确的,因为即使文件存在,(stat)[9]也可以返回0。相反,你需要-e && unlink。这很愚蠢因为您刚刚读取了目录中的文件列表。它也是非原子的。无论内核或文件系统如何表现,它也可能更慢,因为-e代表了许多额外的C代码行。

我的另一个猜测也是优化伏都教。 I found this comment关于在子进程中执行stat,因此inode已经在文件系统缓存中。这不是Perl代码所做的,但它可能是一些货物结果。