web-dev-qa-db-ja.com

`findよりも速いものはありますか。 |ディレクトリ内のファイルをカウントするにはwc-l`?

珍しいことではありませんが、ディレクトリ内のファイルの数を数える必要があります。これは数百万に達することもあります。

find . | wc -lでそれらを列挙して数えるよりも良い方法はありますか? I/Oの負荷が少ないext3/4で実行できるファイルシステム呼び出しの種類はありますか?

8
MattPark

基本的なスピードアップではありませんが、少なくとも何か:)

find . -printf \\n | wc -l

実際には、ファイル名のリストを渡す必要はありません。改行だけで十分です。このバリアントは、ディレクトリがRAMにキャッシュされている場合、Ubuntu 12.04.3で約15%高速です。さらに、このバリアントは、改行を含むファイル名で正しく機能します。

興味深いことに、このバリアントは上記のものよりも少し遅いようです。

find . -printf x | wc -c

特別な場合-しかし本当に速い

ディレクトリが独自のファイルシステム上にある場合は、iノードを数えるだけです。

df -i .

カウントされたもの以外のディレクトリおよびファイルの数があまり変わらない場合は、現在のdf -iの結果からこの既知の数を単純に差し引くことができます。このようにして、ファイルとディレクトリを非常にすばやく数えることができます。

13
pabouk

私はまさにその目的のために ffcnt と書いています。 fiemap ioctlを使用してディレクトリ自体の物理オフセットを取得し、ランダムアクセスを減らすために複数のシーケンシャルパスでディレクトリトラバーサルをスケジュールします。 find | wcと比較して実際にスピードアップできるかどうかは、いくつかの要因によって異なります。

  • ファイルシステムタイプ:fiemapioctlをサポートするext4などのファイルシステムが最もメリットがあります
  • ランダムアクセス速度:HDDはSSDよりもはるかに多くのメリットがあります
  • ディレクトリレイアウト:ネストされたディレクトリの数が多いほど、最適化の可能性が高くなります

relatimeまたはnodiratimeを使用して(再)マウントすると、アクセスによってメタデータが更新される場合に、(すべてのメソッドの)速度が向上する可能性があります。

3
the8472

実際、私のシステム(Arch Linux)ではこのコマンド

   ls -A | wc -l

上記のすべてよりも高速です:

   $ time find . | wc -l
  1893

   real    0m0.027s
   user    0m0.004s
   sys     0m0.004s
   $ time find . -printf \\n  | wc -l
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time find . -printf x  | wc -c
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time ls -A | wc -l
   1892

   real    0m0.007s
   user    0m0.000s
   sys     0m0.004s
2
MariusMatutiae