This article指出了一种使用 perl
清空包含大文件的目录的方法:
perl -e 'for(<*>){((stat)[9]<(unlink))}'
自从它调用 stat
并与每个文件的 unlink
的返回值进行比较后,这让我感到困惑。
我在没有调用 stat
的情况下进行了测试,单行代码更快。在这里调用 stat
的目的是什么?
最佳答案
该统计数据毫无用处,这可能是 cargo 崇拜者在性能优化方面的尝试。
您可以通过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关于在子进程中进行统计,以便 inode 已经在文件系统缓存中。这不是 Perl 代码正在做的事情,但它可能是一些 cargo 崇拜。
关于Perl 一行到空目录解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28715226/