web-dev-qa-db-ja.com

なぜGNUは、グラフィカルファイル検索ユーティリティと比較して高速なのですか?

ホームディレクトリとすべてのサブディレクトリに存在しないファイルを見つけようとしています。

find ~/ -name "bogus"は数秒後にその情報を提供しますが、 KDEのdolphinファイルマネージャー は、同じことを行うのに約3分かかりました。これは、以前の GNOME beagle の経験と一致します。

どのようにfindは、グラフィカル検索(コマンドラインパラメーターよりも直感的に使用できます)が遅れている間、同じように非常に高速に処理できますか?

47
Red

特にBalooでDolphinを見ると、単純なファイル名検索を実行している場合でも、検索ドメイン内のすべてのファイルのメタデータが検索されるようです。 file.soプロセスをトレースすると、lstatgetxattr、およびgetxattrへの呼び出しがすべてのファイルに対して、さらに..エントリに対しても表示されます。これらのシステムコールは、ファイル名とは別の場所に保存されているファイルに関するメタデータを取得します(ファイル名はディレクトリの内容に保存されますが、メタデータは inode にあります)。ファイルのメタデータを複数回クエリすることは、データがディスクキャッシュにあるため安価ですが、メタデータをクエリすることと、メタデータをクエリしないことの間には大きな違いがある可能性があります。

findははるかに賢いです。不要なシステムコールを回避しようとします。拡張属性に基づいて検索しないため、getxattrは呼び出されません。ディレクトリをトラバースする場合、一致しないファイル名に対してlstatを呼び出す必要があります。これは、再帰的に検索するサブディレクトリの場合があるためです(lstatは、ファイルを含むファイルメタデータを返すシステムコールです。 regular/directory/symlink /…などのタイプ)。ただし、findは最適化されています。ディレクトリは link count からディレクトリのサブディレクトリの数を認識し、すべてのサブディレクトリを通過したことがわかると、lstatの呼び出しを停止します。特に、リーフディレクトリ(サブディレクトリのないディレクトリ)では、findは名前のみをチェックし、メタデータはチェックしません。さらに、一部のファイルシステムは、ディレクトリエントリにファイルタイプのコピーを保持しているため、findlstatを呼び出す必要さえなく、必要な情報がそれだけである場合に限ります。

メタデータのチェックを必要とするオプションを指定してfindを実行すると、追加のlstat呼び出しが行われますが、ファイルに対してlstat呼び出しは行われません情報は必要ありません(たとえば、名前に一致する以前の条件によってファイルが除外されているため)。

findホイールを再発明する他のGUI検索ツールは、同様に何十年にもわたる最適化を受けてきたコマンドラインユーティリティよりも賢くないと思います。少なくともイルカは、「どこでも」検索する場合にロケートデータベースを使用するのに十分なほど賢いです(UIでは結果が古くなっている可能性があることは明らかではない制限があります)。