Sembra che find
dovrebbe verificare se un determinato percorso corrisponde comunque a un file o una directory al fine di percorrere ricorsivamente il contenuto delle directory.
Ecco un po 'di motivazione e cosa ho fatto localmente per convincermi che find . -type f
è davvero più lento di find .
. Non ho ancora scavato nella GNU per trovare il codice sorgente.
Quindi eseguo il backup di alcuni dei file nella mia $HOME/Workspace
directory ed escludo i file che dipendono dai miei progetti o dai file di controllo della versione.
Quindi ho eseguito il seguente comando che è stato eseguito rapidamente
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
find
reindirizzato grep
potrebbe essere una cattiva forma, ma sembrava il modo più diretto per utilizzare un filtro regex negato.
Il comando seguente include solo i file nell'output di find e ha impiegato notevolmente più tempo.
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
Ho scritto del codice per testare le prestazioni di questi due comandi (con dash
e tcsh
, solo per escludere qualsiasi effetto che la shell potrebbe avere, anche se non dovrebbe essercene). I tcsh
risultati sono stati omessi perché sono essenzialmente gli stessi.
I risultati ottenuti hanno mostrato una penalità di prestazione del 10% per -type f
Ecco l'output del programma che mostra la quantità di tempo impiegata per eseguire 1000 iterazioni di vari comandi.
% 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
Testato con
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
Su Ubuntu 15.10
Ecco lo script perl che ho usato per il benchmarking
#!/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
e senza di essa. Ma per la prima volta il kernel Linux lo ha caricato nella cache e la prima scoperta è stata più lenta.
-type f
opzione ha causato la find
chiamata stat()
o fstat()
qualsiasi altra cosa per scoprire se il nome del file corrispondeva a un file, una directory, un collegamento simbolico, ecc. Ecc. Ho fatto un strace
su a find .
e a find . -type f
e la traccia era quasi identica, differendo solo nelle write()
chiamate che contenevano nomi di directory. Quindi non lo so, ma voglio sapere la risposta.
time
comando integrato per vedere quanto tempo richiede l'esecuzione di un comando, non è necessario scrivere uno script personalizzato per testare.
find
dovrebbe verificare se un determinato percorso corrisponde comunque a un file o una directory al fine di percorrere ricorsivamente il contenuto delle directory. - dovrebbe verificare se si tratta di una directory, non dovrebbe verificare se si tratta di un file. Esistono altri tipi di voci: named pipe, collegamenti simbolici, blocchi di dispositivi speciali, socket ... Quindi, sebbene possa aver già fatto il controllo per vedere se si tratta di una directory, ciò non significa che sappia se si tratta di un file normale.