Existe algo mais rápido que 'find. | wc -l 'para contar arquivos em um diretório?

8

Não é incomum eu ter que contar o número de arquivos em um diretório, às vezes isso chega aos milhões.

Existe uma maneira melhor do que apenas enumerar e contar com find . | wc -l ? Existe algum tipo de chamada de sistema de arquivos que você pode fazer em ext3 / 4 que seja menos intensivo em E / S?

    
por MattPark 16.12.2013 / 22:39

3 respostas

10

Não é uma aceleração fundamental, mas pelo menos alguma coisa:)

find . -printf \n | wc -l

Você realmente não precisa passar a lista de nomes de arquivos, apenas as novas linhas são suficientes. Esta variante é cerca de 15% mais rápida no meu Ubuntu 12.04.3 quando os diretórios são armazenados em cache na RAM. Além disso, essa variante funcionará corretamente com nomes de arquivos contendo novas linhas.

Curiosamente, esta variante parece ser um pouco mais lenta do que a acima:

find . -printf x | wc -c

Caso especial - mas muito rápido

Se o diretório estiver em seu próprio sistema de arquivos, você pode simplesmente contar os inodes:

df -i .

Se o número de diretórios e arquivos em outros diretórios diferentes do contado não mudarem muito, você pode simplesmente subtrair esse número conhecido do resultado atual df -i . Desta forma, você poderá contar os arquivos e diretórios muito rapidamente.

    
por 17.12.2013 / 00:17
3

Eu escrevi ffcnt exatamente para esse propósito. Ele recupera o deslocamento físico dos próprios diretórios com o fiemap ioctl e, em seguida, agendando o percurso do diretório em vários passos sequenciais para reduzir o acesso aleatório. Se você realmente obter um aumento de velocidade em comparação com find | wc depende de vários fatores:

  • tipo de sistema de arquivos: sistemas de arquivos como ext4 que suportam fiemap ioctl serão os que mais se beneficiarão
  • velocidade de acesso aleatório: os HDDs beneficiam muito mais do que os SSDs
  • layout do diretório: quanto maior o número de diretórios aninhados, maior o potencial de otimização

(re) montagem com relatime ou mesmo nodiratime também pode melhorar a velocidade (para todos os métodos) quando os acessos causariam atualizações de metadados.

    
por 27.01.2017 / 22:53
2

Na verdade, no meu sistema (Arch Linux) este comando

   ls -A | wc -l

é mais rápido que todos os itens acima:

   $ 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
    
por 17.12.2013 / 06:39