Was teuer ist, sind Systemaufrufe für die Dateien (für die Systemaufrufe selbst und für die E / A).
Solche Dinge -type, -mtimeerfordern einen lstat(2)auf dem Dateisystemaufruf. -name, -path, -regexNicht (obwohl natürlich wird es getan Systemaufrufe auf die Verzeichnisse haben sie enthalten , ihre Inhalte zu lesen).
In der findRegel wird eine lstat()ohnehin (weil es wissen muss, ob eine Datei ein Verzeichnis ist oder nicht, um in sie abzusteigen, es sei denn, diese Informationen sind im enthalten readdir()), aber es gibt Fälle, in denen es ohne sie auskommen kann. Wenn beispielsweise die Anzahl der Links eines Verzeichnisses weniger als 3 beträgt, findweiß es in einigen Dateisystemen, dass es keine Unterverzeichnisse hat, und einige findImplementierungen werden optimiert, indem dort kein lstats ausgeführt wird.
-xtypewird ein verursachen stat(2), -printf ..., -lsverursachen ein stat(), lstat(), readlink(), -lnamea lstat()und readlink().
Deshalb möchten Sie vielleicht das -name/ -path/ -regex... an die erste Stelle setzen. Wenn sie eine Datei ausschließen können, können sie einen oder mehrere Systemaufrufe vermeiden.
Nun, ein ist -regexvielleicht teurer als ein -name, aber ich bin mir nicht sicher, ob Sie durch den Austausch viel erreichen würden.
Beachten Sie auch, dass einige findImplementierungen wie GNU finddie Prüfungen nach Möglichkeit standardmäßig neu anordnen. Sehen:
info find 'Optimisation Options'
auf einem GNU-System ( dort auf gnu.org für die neueste Version von GNU findutils).
Wenn Sie Ihre Tests auf einem GNU-System durchgeführt hätten, würden beide Befehle normalerweise dasselbe tun, da findsie den -nameVorgang ohnehin vorwärts verschoben hätten .
Damit das -type d -name ...vs -name ... -type deinen Unterschied macht, benötigen Sie eine findImplementierung, die nicht durch Neuanordnen dieser Prädikate optimiert wird, und eine Implementierung, die einige Optimierungen vornimmt, indem nicht lstat()für jede Datei eine durchgeführt wird.
Wo es unabhängig von der Implementierung einen (großen) Unterschied geben wird, ist:
find . -name 'x*' -exec test -d {} \; -print
vs:
find . -exec test -d {} \; -name 'x*' -print
findIch kann das nicht neu anordnen, -execda dies zu Funktionsunterschieden führen kann ( findich kann nicht wissen, ob der ausgeführte Befehl nur zum Testen dient oder etwas anderes tut).
Und natürlich -exec ... {} \;ist es mehrere Größenordnungen teurer als jedes andere Prädikat, da es bedeutet, einen Prozess zu verzweigen und einen Befehl darin auszuführen (der selbst viele Systemaufrufe ausführt) und auf ihn und seinen Exit-Code zu warten.
$ 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
(Die erste ruft testjede Datei in /usr/lib(56685) auf, die zweite nur für die Dateien, deren Name mit z(147) beginnt .)
Beachten Sie, dass dies -exec test -d {} \;nicht dasselbe ist wie -type d. Es ist das tragbare Äquivalent der GNU-spezifischen -xtype d.
-name ..und von-type dBedeutung ist. Ihre Tests scheinen darauf hinzudeuten, dass dies nicht der Fall ist.