参数顺序如何影响查找速度

Ber*_*ard 7 find

find调用中参数的顺序如何影响结果的速度?

比较例如 (A)

find -name dir -type d
Run Code Online (Sandbox Code Playgroud)

和 (B)

find -type d -name dir
Run Code Online (Sandbox Code Playgroud)

或任何其他参数组合(例如使用-or-and)。我希望find以某种方式变得聪明。

我试图通过执行 A 和 Btime并重复 5 次来收集一些统计数据。然而与

 11.86, 7.23, 5.25, 5.87, 7.16
Run Code Online (Sandbox Code Playgroud)

对于 A 和 B:

9.73, 6.56, 8.69, 7.14, 6.35
Run Code Online (Sandbox Code Playgroud)

这并不是真正的结论,7.5s两者的平均值都在附近,并且差异很大。

那么,重复我的问题,使用 的参数顺序是否重要find

Sté*_*las 11

代价高昂的是对文件进行系统调用(对于系统调用本身和 I/O)。

诸如-type,-mtime需要lstat(2)对文件进行系统调用。-name, -path,-regex不要(当然,它会对它们包含的目录进行系统调用以读取它们的内容)。

通常,find执行lstat()无论如何(因为它需要知道一个文件是否是一个目录或不进入它,除非该信息在 中提供readdir()),但在某些情况下它可以没有它。例如,如果目录的链接数小于 3,那么在某些文件系统中,find知道它没有子目录,并且某些find实现将通过不在lstat那里做s来优化。

-xtype将导致 a stat(2), -printf ...,-ls可能导致 a stat(), lstat(), readlink(), -lnamealstat()readlink()

这就是为什么您可能希望将-name/ -path/ -regex... 放在首位。如果他们可以排除一个文件,他们就可以避免一个或多个系统调用。

现在, a-regex可能比 a 贵-name,但我不太确定交换它们会得到多少。

另请注意,某些find实现(如 GNU)find会在可能的情况下默认对检查重新排序。看:

info find 'Optimisation Options'
Run Code Online (Sandbox Code Playgroud)

在 GNU 系统上(在 gnu.org上有最新版本的 GNU findutils)。

通常,如果您在 GNU 系统上进行测试,两个命令都会做同样的事情,因为无论如何find都会-name向前移动。

因此,要使-type d -name ...vs-name ... -type d有所不同,您需要一种find不通过重新排序这些谓词进行优化的实现,以及一种通过不对lstat()每个文件都进行优化来进行优化的实现。

无论实现如何,都会有(巨大)差异的地方:

find . -name 'x*' -exec test -d {} \; -print
Run Code Online (Sandbox Code Playgroud)

对比:

find . -exec test -d {} \; -name 'x*' -print
Run Code Online (Sandbox Code Playgroud)

find不能重新排序,-exec因为这样做可能会引入功能差异(find无法知道执行的命令是仅用于测试还是执行其他操作)。

当然-exec ... {} \;,这比任何其他谓词都要贵几个数量级,因为它意味着派生一个进程并在其中执行一个命令(它本身运行许多系统调用)并等待它及其退出代码。

$ time find /usr/lib -exec test -d {} \; -name z\* -print > /dev/null
1.03s user 12.52s system 21% cpu 1:03.43 total
$ time find /usr/lib -name z\* -exec test -d {} \;  -print > /dev/null
0.09s user 0.14s system 62% cpu 0.367 total
Run Code Online (Sandbox Code Playgroud)

(第一个调用(56685) 中的test每个文件/usr/lib,第二个仅调用名称以z(147)开头的文件)。

请注意,-exec test -d {} \;这与-type d. 它是 GNU 特定的-xtype d.