Warum ist GNU Find im Vergleich zu grafischen Dateisuchprogrammen so schnell?

47

Ich versuche, eine Datei zu finden, die nicht in meinem Ausgangsverzeichnis und allen Unterverzeichnissen vorhanden ist.

find ~/ -name "bogus"gibt mir diese Information nach ein paar Sekunden, doch der dolphinDateimanager von KDE brauchte fast 3 Minuten, um dasselbe zu tun. Dies entspricht meinen bisherigen Erfahrungen mit GNOMEbeagle .

Wie gelingt findes, dasselbe sehr schnell zu tun, während die grafische Suche (die intuitiver zu bedienen ist als Befehlszeilenparameter) hinterherhinkt?

rot
quelle
Ich weiß nicht, was "Delphin" ist, aber sieht es vielleicht auch in Dateien aus?
Kusalananda
1
Es ist ein grafischer Dateimanager von KDE: kde.org/applications/system/dolphin Er kann in Dateien suchen, aber ich habe diese Option in diesem kurzen Test nicht aktiviert.
Red
9
Haben Sie mehrmals in dolphin gesucht? Möglicherweise wird das erste Mal "indiziert". Und "find" ist auch langsam. Versuchen Sie "locate", wenn die Datei älter als das letzte Mal ist, als die Datenbank für locate indiziert wurde ;-)
Rinzwind
Ich benutze locateöfter als findund es ist schneller in einem riesigen Ordner
phuclv
11
Zwar locateist es sehr gut, Dateien zu finden, aber es ist ein bisschen OT, da es einen völlig anderen Ansatz verwendet: findund GUI-Tools wie Dolphindurchlaufen den Dateibaum bei Bedarf, während locatesie eine zuvor erstellte Indexstruktur verwenden.
Michael Schaefers

Antworten:

68

Wenn Sie Dolphin mit Baloo genauer betrachten, scheint es, als würden die Metadaten jeder Datei in ihrer Suchdomäne nachgeschlagen, selbst wenn Sie eine einfache Suche nach Dateinamen durchführen. Wenn ich den file.soProzess nachverfolge lstat, werden für jede Datei und sogar für Einträge Aufrufe an getxattrund getxattrwieder ..angezeigt. Diese Systemaufrufe rufen Metadaten zu der Datei ab, die an einem anderen Ort als dem Dateinamen gespeichert sind (der Dateiname wird im Verzeichnisinhalt gespeichert, die Metadaten befinden sich jedoch im Inode ). Das mehrmalige Abfragen der Metadaten einer Datei ist kostengünstig, da sich die Daten im Festplatten-Cache befinden. Es kann jedoch einen signifikanten Unterschied zwischen dem Abfragen der Metadaten und dem Nichtabfragen der Metadaten geben.

findist viel schlauer. Es wird versucht, unnötige Systemaufrufe zu vermeiden. Es wird nicht aufgerufen, getxattrda nicht anhand erweiterter Attribute gesucht wird. Wenn es ein Verzeichnis durchläuft, muss es möglicherweise lstatnicht übereinstimmende Dateinamen aufrufen, da dies ein Unterverzeichnis für die rekursive Suche sein kann (dies lstatist der Systemaufruf, der Dateimetadaten einschließlich des Dateityps wie regulär / directory / symlink /… zurückgibt). Es findhat jedoch eine Optimierung: Es erkennt anhand der Verbindungsanzahl , wie viele Unterverzeichnisse ein Verzeichnis hat , und beendet den Aufruf, lstatsobald es weiß, dass es alle Unterverzeichnisse durchlaufen hat. Insbesondere in einem Blattverzeichnis (einem Verzeichnis ohne Unterverzeichnisse)findÜberprüft nur die Namen, nicht die Metadaten. Darüber hinaus behalten einige Dateisysteme eine Kopie des Dateityps im Verzeichniseintrag, sodass findsie nicht einmal aufrufen müssen, lstatwenn dies die einzigen Informationen sind, die sie benötigen.

Wenn Sie findOptionen ausführen, bei denen die Metadaten überprüft werden müssen, werden zwar mehr lstatAufrufe ausgeführt, es wird jedoch trotzdem kein lstatAufruf für eine Datei ausgeführt, wenn die Informationen nicht benötigt werden (z. B. weil die Datei durch eine frühere Bedingung ausgeschlossen ist) passend zum Namen).

Ich vermute, dass andere GUI-Suchwerkzeuge, die das findRad neu erfinden, weniger clever sind als das Kommandozeilen-Dienstprogramm, das jahrzehntelang optimiert wurde. Zumindest Dolphin ist clever genug, um die Suchdatenbank zu verwenden, wenn Sie "überall" suchen (mit der Einschränkung, dass die Ergebnisse möglicherweise nicht mehr aktuell sind).

Gilles 'SO - hör auf böse zu sein'
quelle
22
GNU find ist so "clever", dass einige Dateien auf einigen Dateisystemtypen fehlen. Der bekannte Fehler in der GNU-Suche ist, dass davon ausgegangen wird, dass die Linkanzahl eines Verzeichnisses unzulässig ist. 2 + number of sub-directories.Dies funktioniert für Dateisysteme, die den Design-Fehler aus dem UNIX V7-Dateisystem implementieren, jedoch nicht für alle Dateisysteme, da dies keine POSIX-Anforderung ist . Wenn Sie eine nützliche Performance-Nummer für GNU make erhalten möchten, müssen Sie vorgeben -noleaf, dass sich GNU make korrekt verhält.
schily
12
@schily, GNU findhatte diesen Fehler vielleicht schon vor langer Zeit, aber ich bezweifle, dass Sie einen Fall finden, in dem Sie ihn -noleafheutzutage manuell angeben müssen . AFAICT gibt mindestens unter Linux getdents()(und readdir ()) an, welche Dateien Verzeichnisdateien in UDF, ISO-9660, BTRFS sind, die keine reellen .oder ..Einträge haben, und findverhält sich dort OK. Kennen Sie einen Fall, in dem GNU finddas Problem aufweist?
Stéphane Chazelas
4
Verwenden Sie einfach dieses faule Image von Debian, um ein Rock Ridge-Dateisystem mit "Graft-Points" zu erstellen, und die Anzahl der Links in einem Verzeichnis ist ein zufälliger Wert. Da Rock Ridge eine Linkanzahl und ./. Implementiert, findet GNU find normalerweise nicht alle Dateien auf einem solchen Dateisystem.
schily
4
@ StéphaneChazelas: Als ich das letzte Mal nachgesehen habe (für meine Masterarbeit), wurde der Fehler behoben, indem genau 2 gemeintes bekanntes Blatt und nicht <= 2 angegeben wurden alles ist gut. Wenn nun eines Tages jemand ein Dateisystem erstellt hat, das feste Verknüpfungen zu Verzeichnissen erstellt hat, die diese Eigenschaft nicht haben, wird jemand einen schlechten Tag haben.
Joshua
15
@schily, ich war nicht in der Lage, zufällige Link-Zählungen mit Graft-Punkten und RR mit Genisoimage 1.1.11 unter Debian zu erhalten, und selbst wenn ich das ISO-Image binär bearbeite, um die Link-Zählungen in zufällige Werte zu ändern, sehe ich immer noch keine Problem mit GNU find. Und zeigt auf jeden Fall, strace -vdass getdents()d_type = DT_DIR für Verzeichnisse korrekt zurückgegeben wird, sodass GNU find den Link Count Trick nicht verwenden muss.
Stéphane Chazelas