GNU/Linux >> Linux の 問題 >  >> Linux

なぜ`は見つけるのですか。 -タイプF`は`find.`よりも時間がかかりますか?

findのようです ディレクトリの内容を再帰的にウォークするには、特定のパスがファイルまたはディレクトリに対応しているかどうかを確認する必要があります。

find . -type f 本当にfind . 。 GNUの検索ソースコードはまだ掘り下げていません。

そのため、$HOME/Workspace内のいくつかのファイルをバックアップしています ディレクトリを作成し、プロジェクトの依存関係またはバージョン管理ファイルのいずれかであるファイルを除外します。

そこで、すばやく実行される次のコマンドを実行しました

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

find grepにパイプされます 悪い形式かもしれませんが、否定された正規表現フィルターを使用する最も直接的な方法のように見えました。

次のコマンドには、findの出力に含まれるファイルのみが含まれ、著しく時間がかかりました。

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

これら2つのコマンドのパフォーマンスをテストするためのコードをいくつか作成しました(dashを使用) およびtcsh 、シェルが持つ可能性のある影響を除外するためだけに、存在してはならない場合でも)。 tcsh 結果は基本的に同じであるため、省略されています。

私が得た結果は、-type fに対して約10%のパフォーマンスペナルティを示しました。

これは、さまざまなコマンドの1000回の反復を実行するのにかかる時間を示すプログラムの出力です。

% 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

でテスト済み

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

Ubuntu15.10の場合

これが私がベンチマークに使用したperlスクリプトです

#!/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);
    }
}

承認された回答:

GNU findには、find .に適用できる最適化があります。 ただし、find . -type f :ディレクトリ内の残りのエントリがいずれもディレクトリではないことがわかっている場合は、ファイルタイプをわざわざ判断する必要はありません(statを使用)。 システムコール)検索条件の1つがそれを必要としない限り。 statを呼び出す 情報は通常、含まれているディレクトリではなく、ディスク上の別の場所にあるiノードにあるため、測定可能な時間がかかる場合があります。

関連:不規則な間隔で仕事をスケジュールしますか?

どうやって知るの?ディレクトリのリンク数は、そのディレクトリにあるサブディレクトリの数を示しているためです。一般的なUnixファイルシステムでは、ディレクトリのリンク数は2にディレクトリの数を加えたものです。1つは親のディレクトリのエントリ用で、もう1つは. エントリ、および..用に1つ 各サブディレクトリのエントリ。

-noleaf オプションはfindに指示します この最適化を適用しないでください。これは、findの場合に便利です ディレクトリリンク数がUnixの規則に従わないファイルシステムで呼び出されます。


Linux
  1. Find -mtime +1が2日より古いファイルのみを返すのはなぜですか?

  2. /dev/shm/ と /tmp/ はいつ使用する必要がありますか?

  3. プロセスが実行されているフォルダーを見つける方法は?

  1. 間違ったパスワードを試行すると、正しいパスワードよりも処理に時間がかかるのはなぜですか?

  2. Linux が NVMe ドライブを /dev/sda ではなく /dev/nvme0 としてリストするのはなぜですか?

  3. この正規表現が Linux で機能しないのはなぜですか?

  1. Linux がファイルではなくスワップ パーティションを使用するのはなぜですか?

  2. /proc/meminfo の MemTotal が変更されるのはなぜですか?

  3. USB スティックの検出に時間がかかるのはなぜですか?