findDizinlerin 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 fdaha 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/Workspaceve 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
findborulu grepolabilir, 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 ( dashve tcsh, herhangi bir olmamasına rağmen kabuğun sahip olabileceği herhangi bir etkiyi ekarte etmek için). tcshOnlar 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 fseçenek sebep findaramak 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 stracebir üstünde find . ve find . -type fve iz neredeyse aynıydı, yalnızca içinde write()dizin adları olan aramalarda farklılık gösterir . Yani bilmiyorum, ama cevabı bilmek istiyorum.
timebir 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.
findDizinlerin 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.