Befehl 'ls' sehr langsam

3

Ich habe ungefähr 17k Akten in einem Verzeichnis. Wenn ich renne ls directory, muss ich ungefähr 15-20 Sekunden warten, bevor die Ergebnisse angezeigt werden. Wenn ich dagegen ls directory | wc -loder starte ls directory | grep .xyz, werden die Ergebnisse sofort angezeigt.

Warum passiert dies und gibt es eine Möglichkeit, dies zu beheben?

Tytywin
quelle
1
Dies liegt daran, dass sich 17.000 Dateien im Verzeichnis befinden. Die Lösung besteht darin, weniger Dateien im Verzeichnis zu haben.
Ignacio Vazquez-Abrams
Das Drucken auf die Konsole ist immer langsam. Wenn OTOH die Daten durch eine Pipe leitet, verbleibt die Ausgabe im Speicher oder in der Datei, sodass sie viel schneller ist
phuclv
Dieses Problem hängt mit dem Anzeigepuffer (?) Der Konsole zusammen. Die "Langsamkeit" entsteht durch die Ausgabe der Daten über den Puffer, nicht durch den Befehl selbst.
Konfetti
@ IgnacioVazquez-Abrams Was ist, wenn Sie ein ML-Ingenieur sind?
Tytywin
Ich würde einen besseren Weg finden, um die Daten zu organisieren.
Ignacio Vazquez-Abrams

Antworten:

5

Ich gehe davon aus, dass Sie Linux verwenden.

  1. Wenn Ihr lsBefehl so ausgerichtet ist, dass er Dateien und Ordner in Farbe anzeigt, muss er die Berechtigungen jedes Elements (einen stat () -Aufruf) ermitteln und feststellen, ob "Dateifunktionen" festgelegt wurden (einen getxattr () -Aufruf) um die richtige Farbe zu wählen. Je nach Dateisystem können diese Aufrufe relativ langsam sein, wenn die erforderlichen Metadaten noch nicht im RAM zwischengespeichert wurden. [Erweiterte Attribute befinden sich häufig im Datenbereich, sodass bei jedem getxattr die Suche auf der Festplatte ausgeführt wird.]

    Auf der anderen Seite, ls |wenn sie auf ein Rohr umgeleitet automatisch deaktiviert Färbung, so dass es nicht mehr irgendwelche zusätzliche Kontrollen tun muss - nur eine einfache readdir () Schleife , die die Dateinamen und Typen zurückgibt, und die Kernel wahrscheinlich sogar Geräte lesen grünes Licht für Das.

  2. Normalerweise wird lsdie Ausgabe in Spalten unterteilt, was bedeutet, dass das gesamte Verzeichnis gelesen werden muss, bevor überhaupt etwas ausgegeben werden kann. Beim Durchlaufen einer Pipe wird der Spaltenmodus automatisch deaktiviert und diese Pufferung wird nicht mehr benötigt. (Die Gesamtlaufzeit muss nicht unbedingt kürzer sein, aber die Ausgabe beginnt früher, sodass sie sich reaktionsschneller anfühlt.)

Verwenden Sie straceoder perf trace, um zu überprüfen, welche Systemaufrufe lange dauern.

Grawity
quelle
Aber ls directory | wc -lerzeugt keine Ausgabe erst nach dem lsabschließt. Und selbst wenn Sie auf etwas anderes als ein Terminal schreiben, wird das Verzeichnis standardmäßig ls sortiert , sodass es immer noch nichts ausgeben kann, bevor es das gesamte Verzeichnis gelesen hat.
Scott
1
Ja, der 2. Teil des Beitrags ist größtenteils Unsinn. Der Hauptunterschied besteht darin, lstat () / getxattr () aufrufen zu müssen.
Grawity
0

Zwei Dinge:

  1. Wenn Sie lszuerst und ls | wc -lspäter ausführen , liest möglicherweise der Erstere Daten von Ihrer Festplatte, und der Letztere liest zwischengespeicherte Daten. In diesem Fall wird lszunächst "angehalten" und einige Sekunden lang nichts gedruckt. Ein anderer lsDruckvorgang wird fast sofort gestartet, solange die zwischengespeicherten Daten noch vorhanden sind. Wenn Sie mit beginnen ls | wc -lin erster Linie, es würde warten müssen für HDD Daten zu versorgen.
  2. Jedes Terminal arbeitet mit seiner eigenen Geschwindigkeit. Formal stty speedwird Ihnen etwas Wert zeigen, aber ich denke, dass es für ein virtuelles Terminal keine Rolle spielt. Das Anzeigen von Zeichen und Scrollen nimmt jedoch einige Zeit in Anspruch (siehe diese Frage ). Das Weitergeben derselben Daten durch eine Pipe ist schneller.
Kamil Maciorowski
quelle
Sie schlagen vor, dass das Schreiben auf das Display ein wichtiger Faktor für das Timing ist. Dies kann mit einigen Experimenten getestet werden: Führen Sie die folgenden Befehle aus: ls -C directory > tmp(Hinzufügen, --color=alwayswenn  lsnormalerweise ein Alias ​​für die Verwendung verwendet wird --color) cat tmp, und ls directory | catund schauen Sie sich an, wie lange sie dauern.
Scott
@Scott Ich schlage vor, es kann sein, vor allem wenn man gerne benutzt /dev/tty2. Ich habe ein Verzeichnis mit 200.000 Dateien und muss es nicht einmal gründlich testen. Mit /dev/tty2dem Befehl scrollen und scrollen und scrollen ... und konsolein kürzester Zeit drucken. Geradlinige time lsergab 30s und 1.4S verbunden sind; für ls | wc -ldiese war 0,5s in beiden Terminals. Alle Tests wurden nach der Erstinbetriebnahme durchgeführt ls, bei denen tatsächlich Daten von meiner nicht so schnellen Festplatte abgerufen und vom Betriebssystem zwischengespeichert wurden. Die Ergebnisse sind wiederholbar.
Kamil Maciorowski