ホームディレクトリとすべてのサブディレクトリに存在しないファイルを見つけようとしています。
find ~/ -name "bogus"
は数秒後にその情報を提供しますが、 KDEのdolphin
ファイルマネージャー は、同じことを行うのに約3分かかりました。これは、以前の GNOME beagle
の経験と一致します。
どのようにfind
は、グラフィカル検索(コマンドラインパラメーターよりも直感的に使用できます)が遅れている間、同じように非常に高速に処理できますか?
特にBalooでDolphinを見ると、単純なファイル名検索を実行している場合でも、検索ドメイン内のすべてのファイルのメタデータが検索されるようです。 file.so
プロセスをトレースすると、lstat
、getxattr
、およびgetxattr
への呼び出しがすべてのファイルに対して、さらに..
エントリに対しても表示されます。これらのシステムコールは、ファイル名とは別の場所に保存されているファイルに関するメタデータを取得します(ファイル名はディレクトリの内容に保存されますが、メタデータは inode にあります)。ファイルのメタデータを複数回クエリすることは、データがディスクキャッシュにあるため安価ですが、メタデータをクエリすることと、メタデータをクエリしないことの間には大きな違いがある可能性があります。
find
ははるかに賢いです。不要なシステムコールを回避しようとします。拡張属性に基づいて検索しないため、getxattr
は呼び出されません。ディレクトリをトラバースする場合、一致しないファイル名に対してlstat
を呼び出す必要があります。これは、再帰的に検索するサブディレクトリの場合があるためです(lstat
は、ファイルを含むファイルメタデータを返すシステムコールです。 regular/directory/symlink /…などのタイプ)。ただし、find
は最適化されています。ディレクトリは link count からディレクトリのサブディレクトリの数を認識し、すべてのサブディレクトリを通過したことがわかると、lstat
の呼び出しを停止します。特に、リーフディレクトリ(サブディレクトリのないディレクトリ)では、find
は名前のみをチェックし、メタデータはチェックしません。さらに、一部のファイルシステムは、ディレクトリエントリにファイルタイプのコピーを保持しているため、find
がlstat
を呼び出す必要さえなく、必要な情報がそれだけである場合に限ります。
メタデータのチェックを必要とするオプションを指定してfind
を実行すると、追加のlstat
呼び出しが行われますが、ファイルに対してlstat
呼び出しは行われません情報は必要ありません(たとえば、名前に一致する以前の条件によってファイルが除外されているため)。
find
ホイールを再発明する他のGUI検索ツールは、同様に何十年にもわたる最適化を受けてきたコマンドラインユーティリティよりも賢くないと思います。少なくともイルカは、「どこでも」検索する場合にロケートデータベースを使用するのに十分なほど賢いです(UIでは結果が古くなっている可能性があることは明らかではない制限があります)。