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

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

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

比较例如(A)

find -name dir -type d

和(B)

find -type d -name dir

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

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

 11.86, 7.23, 5.25, 5.87, 7.16

对于 A 和 B:

9.73, 6.56, 8.69, 7.14, 6.35

这并不是真正的结论,两者的平均值都在附近7.5s,并且方差相当高。

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

答案1

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

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

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

-xtype会导致stat(2), -printf ...,可能-ls导致stat(), lstat(), readlink(),-lnamelstat().readlink()

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

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

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

info find 'Optimisation Options'

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

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

因此,为了使-type d -name ...vs-name ... -type d发挥作用,您需要一种find不通过对这些谓词重新排序来进行优化的实现,以及一种通过不在lstat()每个文件上执行 an 来进行一些优化的实现。

无论实施如何,都会存在(巨大)差异:

find . -name 'x*' -exec test -d {} \; -print

对比:

find . -exec test -d {} \; -name 'x*' -print

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

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

请注意,-exec test -d {} \;与 不一样-type d。它是 GNU 特定的可移植版本-xtype d

相关内容