Parece find
que tendría que verificar si una ruta determinada corresponde a un archivo o directorio de todos modos para recorrer recursivamente el contenido de los directorios.
Aquí hay algo de motivación y lo que he hecho localmente para convencerme de que find . -type f
realmente es más lento que find .
. Todavía no he profundizado en el código fuente de GNU find.
Así que estoy haciendo una copia de seguridad de algunos de los archivos en mi $HOME/Workspace
directorio y excluyendo los archivos que son dependencias de mis proyectos o archivos de control de versiones.
Entonces ejecuté el siguiente comando que se ejecutó rápidamente
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
find
canalizado a grep
puede ser de mal gusto, pero parecía que el camino más directo para utilizar un filtro de expresiones regulares negada.
El siguiente comando incluye solo archivos en la salida de find y tomó notablemente más tiempo.
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
Escribí un código para probar el rendimiento de estos dos comandos (con dash
y tcsh
, solo para descartar cualquier efecto que pueda tener el shell, aunque no debería haber ninguno). Los tcsh
resultados se han omitido porque son esencialmente los mismos.
Los resultados que obtuve mostraron una penalización de rendimiento del 10% por -type f
Aquí está la salida del programa que muestra la cantidad de tiempo necesario para ejecutar 1000 iteraciones de varios comandos.
% 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
Probado con
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
En Ubuntu 15.10
Aquí está el script perl que utilicé para la evaluación comparativa
#!/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
y sin él. Pero al principio, el kernel de Linux lo cargó en caché y el primer hallazgo fue más lento.
-type f
opción causado find
a llamar stat()
o fstat()
o lo que sea con el fin de averiguar si el nombre de archivo corresponde a un archivo, un directorio, un enlace simbólico, etc, etc hice una strace
en una find .
y una find . -type f
y la traza era casi idéntica, solo difiere en las write()
llamadas que tenían nombres de directorio en ellas. Entonces, no sé, pero quiero saber la respuesta.
time
comando incorporado para ver cuánto tiempo tarda un comando en ejecutarse, realmente no necesitaba escribir un script personalizado para probar.
find
que tendría que verificar si una ruta determinada corresponde a un archivo o directorio de todos modos para recorrer recursivamente el contenido de los directorios. - tendría que verificar si es un directorio, no tendría que verificar si es un archivo. Existen otros tipos de entradas: canalizaciones con nombre, enlaces simbólicos, dispositivos especiales de bloque, enchufes ... Por lo tanto, aunque ya haya realizado la comprobación para ver si es un directorio, no significa que sepa si es un archivo normal.