Ich versuche, den Zeitstempel für alle XML-Dateien in meinem Verzeichnis (rekursiv) auf die aktuelle Zeit zu aktualisieren. Ich verwende Mac OSX 10.8.5.
Für ungefähr 300.000 Dateien echo
dauert der folgende Befehl 10 Sekunden :
for file in `find . -name "*.xml"`; do echo >> $file; done
Der folgende touch
Befehl dauert jedoch 10 Minuten ! :
for file in `find . -name "*.xml"`; do touch $file; done
Warum ist das Echo hier so viel schneller als die Berührung?
echo >> $file
wird eine neue Zeile angehängt$file
und somit geändert . Ich gehe davon aus, dass es für OS / X dasselbe sein wird. Wenn Sie das nicht wollen, verwenden Sieecho -n >> $file
.touch `find . -name "*.xml"`
noch schneller als die beiden oben?>>$file
touch
so oft aufrufen ?find . -name '*.xml' -print0 | xargs -0 touch
rufttouch
viel seltener auf (möglicherweise nur einmal). Funktioniert unter Linux, sollte unter OS X funktionieren.Antworten:
In bash
touch
ist es eine externe Binärdatei, aber esecho
ist eine eingebaute Shell :Da
touch
es sich um eine externe Binärdatei handelt und Sie diesetouch
einmal pro Datei aufrufen , muss die Shell 300.000 Instanzen von erstellentouch
, was sehr lange dauert.echo
Es handelt sich jedoch um ein Shell-Builtin, und für die Ausführung von Shell-Builtins ist kein Forking erforderlich. Stattdessen führt die aktuelle Shell alle Vorgänge aus, und es werden keine externen Prozesse erstellt. das ist der Grund, warum es so viel schneller ist.Hier sind zwei Profile der Shell-Operationen. Sie sehen, dass beim Klonen neuer Prozesse viel Zeit aufgewendet wird
touch
. Die Verwendung/bin/echo
der eingebauten Shell sollte zu einem viel vergleichbareren Ergebnis führen.Mit Berührung
Echo verwenden
quelle
Wie andere geantwortet haben, ist using
echo
schneller alstouch
asecho
ein Befehl, der normalerweise in die Shell integriert ist (obwohl dies nicht erforderlich ist). Durch die Verwendung entfällt der Kernel-Overhead, der mit dem Starten eines neuen Prozesses für jede Datei verbunden ist, die Sie erhaltentouch
.Beachten Sie jedoch, dass der schnellste Weg, um diesen Effekt zu erzielen, immer noch die Verwendung
touch
ist. Statt das Programm einmal für jede Datei auszuführen , können Sie die-exec
Option mit verwenden,find
um sicherzustellen, dass sie nur einige Male ausgeführt wird. Dieser Ansatz ist normalerweise schneller, da der mit einer Shell-Schleife verbundene Overhead vermieden wird:Bei Verwendung von
+
(im Gegensatz zu\;
) mit wirdfind ... -exec
der Befehl, wenn möglich, nur einmal mit jeder Datei als Argument ausgeführt. Wenn die Argumentliste sehr lang ist (wie dies bei 300.000 Dateien der Fall ist), werden mehrere Durchläufe mit einer Argumentliste durchgeführt, deren Länge nahe am Limit liegt (ARG_MAX
auf den meisten Systemen).Ein weiterer Vorteil dieses Ansatzes besteht darin, dass er sich stabil mit Dateinamen verhält, die alle Leerzeichen enthalten, was bei der ursprünglichen Schleife nicht der Fall ist.
quelle
+1
um auf das find-+
Argument hinzuweisen . Ich denke, viele Leute sind sich dessen nicht bewusst (ich war es nicht).find
haben das+
Argument. Sie können einen ähnlichen Effekt erzielen, indem Sie an leitenxargs
.+
Teil wird von POSIX benötigt, sollte also portabel sein.-print0
ist nicht.find
die verfügbare Option hat, sie aber einfach wie eine;
unter der Oberfläche behandelt.echo
ist eine eingebaute Shell. Auf der anderen Seitetouch
ist eine externe Binärdatei.Shell-Buildins sind viel schneller, da beim Laden des Programms kein Overhead anfällt , dh es ist kein
fork
/exec
beteiligt. Als solches würden Sie einen signifikanten Zeitunterschied feststellen, wenn Sie einen eingebauten Befehl häufig im Vergleich zu einem externen Befehl ausführen.Dies ist der Grund, warum Dienstprogramme wie diese
time
als Shell-Buildins verfügbar sind.Sie können die vollständige Liste der Shell-Buildins abrufen, indem Sie sagen:
Wie oben erwähnt, führt die Verwendung des Dienstprogramms im Gegensatz zum eingebauten Dienstprogramm zu einer signifikanten Leistungsverschlechterung. Im Folgenden finden Sie eine Statistik über die Zeit, die zum Erstellen von ~ 9000 Dateien mithilfe der integrierten Funktion
echo
und des Dienstprogramms benötigt wurdeecho
:quelle
echo
Binärdatei auf den meisten Systemen (für mich ist es/bin/echo
), so dass Sie die Timing-Tests mit dieser anstelle der eingebauten wiederholen können