find
Dizinlerin içeriğini yinelemeli olarak yürütebilmek için belirli bir yolun bir dosyaya veya dizine karşılık gelip gelmediğini kontrol etmek gibi görünüyor .
İşte biraz motivasyon ve kendimi find . -type f
daha yavaş olduğuna ikna etmek için yerel olarak yaptığım şey find .
. Henüz GNU bulma kaynak koduna girmedim.
Bu yüzden dizinimdeki bazı dosyaları yedekliyorum $HOME/Workspace
ve projelerimin veya sürüm kontrol dosyalarının bağımlılığı olan dosyaları hariç tutuyorum.
Bu yüzden hızlı bir şekilde yürütülen aşağıdaki komutu çalıştırdım
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
find
borulu grep
olabilir, ancak olumsuz bir normal ifade filtresi kullanmanın en doğrudan yolu gibi görünüyordu.
Aşağıdaki komut yalnızca find çıktısındaki dosyaları içerir ve fark edilir şekilde daha uzun sürdü.
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
Bu iki komutun performansını test etmek için bazı kodlar yazdım ( dash
ve tcsh
, herhangi bir olmamasına rağmen kabuğun sahip olabileceği herhangi bir etkiyi ekarte etmek için). tcsh
Onlar temelde aynı çünkü sonuçlar atlanmıştır.
Aldığım sonuçlar% 10 performans cezası gösterdi -type f
İşte çeşitli komutların 1000 yinelemesini yürütmek için geçen süreyi gösteren program çıktısı.
% 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
İle test edildi
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
Ubuntu 15.10
Kıyaslama için kullandığım perl betiği
#!/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
. Ancak Linux çekirdeği ilk defa önbelleğe yükledi ve ilk bulma işlemi daha yavaştı.
-type f
seçenek sebep find
aramak stat()
veya fstat()
dosya adı bir dosyaya karşılık öğrenmek için ya da her türlü sırayla, vb vb ben yaptım bir dizin, bir sembolik strace
bir üstünde find .
ve find . -type f
ve iz neredeyse aynıydı, yalnızca içinde write()
dizin adları olan aramalarda farklılık gösterir . Yani bilmiyorum, ama cevabı bilmek istiyorum.
time
bir komutun yürütülmesinin ne kadar sürdüğünü görmek için yerleşik bir komut var, gerçekten test etmek için özel bir komut dosyası yazmanıza gerek yoktu.
find
Dizinlerin içeriğini yinelemeli olarak yürütebilmek için belirli bir yolun bir dosyaya veya dizine karşılık gelip gelmediğini kontrol etmek gibi görünüyor . - bir dizin olup olmadığını kontrol etmek zorunda kalacak, bir dosya olup olmadığını kontrol etmek zorunda olmayacaktı. Başka giriş türleri de var: adlandırılmış borular, sembolik bağlantılar, özel aygıtları engelle, soketler ... Bu nedenle, bir dizin olup olmadığını görmek için kontrolü yapmış olsa da, normal bir dosya olup olmadığını bildiği anlamına gelmez.