GNU/Linux >> Belajar Linux >  >> Linux

Mengapa `menemukan . -type F` Lebih Lama Dari `find .`?

Sepertinya find harus memeriksa apakah jalur yang diberikan sesuai dengan file atau direktori untuk menelusuri konten direktori secara rekursif.

Berikut beberapa motivasi dan apa yang telah saya lakukan secara lokal untuk meyakinkan diri saya sendiri bahwa find . -type f benar-benar lebih lambat dari find . . Saya belum menggali kode sumber GNU find.

Jadi saya mencadangkan beberapa file di $HOME/Workspace saya direktori, dan mengecualikan file yang merupakan dependensi proyek saya atau file kontrol versi.

Jadi saya menjalankan perintah berikut yang dieksekusi dengan cepat

% find Workspace/ | grep -v '/vendor|/node_modules/|Workspace/sources/|/venv/|/.git/' > ws-files-and-dirs.txt

find disalurkan ke grep mungkin bentuk yang buruk, tetapi sepertinya cara paling langsung untuk menggunakan filter regex yang dinegasikan.

Perintah berikut hanya menyertakan file dalam output find dan membutuhkan waktu lebih lama.

% find Workspace/ -type f | grep -v '/vendor|/node_modules/|Workspace/sources/|/venv/|/.git/' > ws-files-only.txt

Saya menulis beberapa kode untuk menguji kinerja kedua perintah ini (dengan dash dan tcsh , hanya untuk mengesampingkan efek apa pun yang mungkin dimiliki shell, meskipun seharusnya tidak ada). tcsh hasil telah dihilangkan karena pada dasarnya sama.

Hasil yang saya dapatkan menunjukkan tentang penalti kinerja 10% untuk -type f

Berikut adalah output dari program yang menunjukkan jumlah waktu yang dibutuhkan untuk mengeksekusi 1000 iterasi dari berbagai perintah.

% 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

Diuji dengan

% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.

Di Ubuntu 15.10

Ini skrip perl yang saya gunakan untuk 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 "%snn", time_command(@$shell, $command);
    }
}

Jawaban yang Diterima:

GNU find memiliki pengoptimalan yang dapat diterapkan ke find . tetapi tidak untuk find . -type f :jika mengetahui bahwa tidak ada entri yang tersisa dalam direktori adalah direktori, maka tidak perlu repot menentukan jenis file (dengan stat panggilan sistem) kecuali salah satu kriteria pencarian memerlukannya. Memanggil stat dapat memakan waktu yang terukur karena informasi biasanya ada di inode, di lokasi terpisah di disk, daripada di direktori yang memuatnya.

Terkait:Jadwalkan pekerjaan pada interval yang tidak teratur?

Bagaimana itu tahu? Karena jumlah tautan pada direktori menunjukkan berapa banyak subdirektori yang dimilikinya. Pada sistem file Unix biasa, jumlah tautan direktori adalah 2 ditambah jumlah direktori:satu untuk entri direktori di induknya, satu untuk . entri, dan satu untuk .. entri di setiap subdirektori.

-noleaf opsi memberitahu find untuk tidak menerapkan pengoptimalan ini. Ini berguna jika find dipanggil pada beberapa sistem file di mana jumlah tautan direktori tidak mengikuti konvensi Unix.


Linux
  1. Mengapa Find -mtime +1 Hanya Mengembalikan File Lebih Lama dari 2 Hari?

  2. Mengapa /bin/sh Menunjuk Ke /bin/dash Dan Bukan /bin/bash??

  3. Mengapa find -exec mv {} ./target/ + tidak berfungsi?

  1. Kapan saya harus menggunakan /dev/shm/ dan kapan saya harus menggunakan /tmp/?

  2. Mengapa Linux mencantumkan drive NVMe sebagai /dev/nvme0 bukan /dev/sda?

  3. Mengapa regex ini tidak berfungsi di linux?

  1. Mengapa MemTotal di /proc/meminfo berubah?

  2. Mengapa pada beberapa sistem Linux, sistem file root muncul sebagai /dev/root bukan /dev/<real device node>di mtab?

  3. Haruskah situs web berada di /var/ atau /usr/ sesuai dengan penggunaan yang disarankan?