Es scheint, als find
müsste geprüft werden, ob ein angegebener Pfad einer Datei oder einem Verzeichnis entspricht, um den Inhalt von Verzeichnissen rekursiv zu durchsuchen.
Hier ist ein wenig Motivation und was ich vor Ort getan habe, um mich davon zu überzeugen, dass es find . -type f
wirklich langsamer ist als find .
. Ich habe mich noch nicht mit dem GNU-Find-Quellcode beschäftigt.
Daher sichere ich einige der Dateien in meinem $HOME/Workspace
Verzeichnis und schließe Dateien aus, bei denen es sich entweder um Abhängigkeiten meiner Projekte oder um Versionskontrolldateien handelt.
Also habe ich den folgenden Befehl ausgeführt, der schnell ausgeführt wurde
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
find
Eine Pipe zu grep
einer schlechten Form mag sein, aber es schien der direkteste Weg zu sein, einen negierten Regex-Filter zu verwenden.
Der folgende Befehl bezieht nur Dateien in die Ausgabe von find ein und hat deutlich länger gedauert.
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
Ich habe Code geschrieben, um die Leistung dieser beiden Befehle zu testen (mit dash
und tcsh
, um mögliche Effekte der Shell auszuschließen, auch wenn es keine geben sollte). Die tcsh
Ergebnisse wurden weggelassen, da sie im Wesentlichen gleich sind.
Die Ergebnisse, die ich erhalten habe, zeigten eine 10% ige Leistungsstrafe für -type f
Hier ist die Ausgabe des Programms, die die Zeit angibt, die für die Ausführung von 1000 Iterationen verschiedener Befehle benötigt wurde.
% perl tester.pl
/bin/sh -c find Workspace/ >/dev/null
82.986582
/bin/sh -c find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
90.313318
/bin/sh -c find Workspace/ -type f >/dev/null
102.882118
/bin/sh -c find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
109.872865
Getestet mit
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
Unter Ubuntu 15.10
Hier ist das Perl-Skript, das ich für das Benchmarking verwendet habe
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[gettimeofday tv_interval];
my $max_iterations = 1000;
my $find_everything_no_grep = <<'EOF';
find Workspace/ >/dev/null
EOF
my $find_everything = <<'EOF';
find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my $find_just_file_no_grep = <<'EOF';
find Workspace/ -type f >/dev/null
EOF
my $find_just_file = <<'EOF';
find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my @finds = ($find_everything_no_grep, $find_everything,
$find_just_file_no_grep, $find_just_file);
sub time_command {
my @args = @_;
my $start = [gettimeofday()];
for my $x (1 .. $max_iterations) {
system(@args);
}
return tv_interval($start);
}
for my $shell (["/bin/sh", '-c']) {
for my $command (@finds) {
print "@$shell $command";
printf "%s\n\n", time_command(@$shell, $command);
}
}
-type f
und ohne ausgeführt werden. Aber beim ersten Mal hat der Linux-Kernel ihn in den Cache geladen und der erste Fund war langsamer.
-type f
Option verursacht find
anrufen stat()
oder fstat()
oder was auch immer , um herauszufinden, ob der Dateiname in eine Datei entsprach, ein Verzeichnis, ein symbolischer Link, etc etc. Ich habe ein strace
auf ein find .
und ein find . -type f
und die Spur war fast identisch, unterscheidet sich nur in den write()
Aufrufen, die Verzeichnisnamen in ihnen hatten. Also, ich weiß es nicht, aber ich möchte die Antwort wissen.
time
eingebauten Befehl, mit dem Sie feststellen können, wie lange die Ausführung eines Befehls dauert. Sie mussten zum Testen nicht unbedingt ein benutzerdefiniertes Skript schreiben.
find
müsste geprüft werden, ob ein angegebener Pfad einer Datei oder einem Verzeichnis entspricht, um den Inhalt von Verzeichnissen rekursiv zu durchsuchen. - Es müsste überprüft werden, ob es sich um ein Verzeichnis handelt. Es müsste nicht überprüft werden, ob es sich um eine Datei handelt. Es gibt noch andere Eintragsarten: Named Pipes, symbolische Links, Blockieren spezieller Geräte, Sockets ... Obwohl bereits geprüft wurde, ob es sich um ein Verzeichnis handelt, bedeutet dies nicht, dass es weiß, ob es sich um eine reguläre Datei handelt.