Faux Pas: O método "rápido" que mencionei abaixo, não é 60 vezes mais rápido que o lento. É 30 vezes mais rápido. Eu culpo o erro na hora (03:00 não é a minha melhor hora do dia para um pensamento claro :) ..
Atualização: adicionei um resumo dos tempos de teste (abaixo).
Parece haver dois problemas envolvidos com o fator de velocidade:
- A escolha do comando usado (comparações de tempo mostradas abaixo)
- A natureza de um grande número de arquivos em um diretório ... Parece que "grande é ruim". As coisas ficam desproporcionalmente mais lentas à medida que os números aumentam.
Todos os testes foram feitos com 1 milhão de arquivos.
(os horários real, do usuário e do sys estão nos scripts de teste)
Os scripts de teste podem ser encontrados em paste.ubuntu.com
#
# 1 million files
# ===============
#
# |time |new dir |Files added in ASCENDING order
# +---- +------- +-------------------------------------------------
# real 01m 33s Add files only (ASCENDING order) ...just for ref.
# real 02m 04s Add files, and make 'rm' source (ASCENDING order)
# Add files, and make 'rm' source (DESCENDING order)
# real 00m 01s Count of filenames
# real 00m 01s List of filenames, one per line
# ---- ------- ------
# real 01m 34s 'rm -rf dir'
# real 01m 33s 'rm filename' via rm1000filesPerCall (1000 files per 'rm' call)
# real 01m 40s 'rm filename' via ASCENDING algorithm (1000 files per 'rm' call)
# real 01m 46s 'rm filename' via DESCENDING algorithm (1000 files per 'rm' call)
# real 21m 14s 'rm -r dir'
# real 21m 27s 'find dir -name "hello*" -print0 | xargs -0 -n 1000 rm'
# real 21m 56s 'find dir -name "hello*" -delete'
# real 23m 09s 'find dir -name "hello*" -print0 | xargs -0 -P 0 rm'
# real 39m 44s 'rm filename' (one file per rm call) ASCENDING
# real 47m 26s 'rm filename' (one file per rm call) UNSORTED
#
Recentemente, criei e excluí 10 milhões de arquivos de teste vazios. Excluindo arquivos por nome (por exemplo rm filename
), descobri da maneira mais difícil que existe uma enorme diferença de tempo entre dois métodos diferentes ...
Ambos os métodos usam exatamente o mesmo rm filename
comando.
Atualização: como se vê, os comandos não eram exatamente os mesmos ... Um deles estava enviando 1000 nomes de arquivos de cada vez para 'rm' ... Era um problema de expansão de chave de shell em que eu pensava que cada nome de arquivo estava sendo escrito para o arquivo do alimentador em uma linha própria, mas na verdade era de 1000 por linha
Os nomes dos arquivos são fornecidos por meio de um 'arquivo alimentador' em um while read
loop.
O arquivo alimentador é a saída de ls -1 -f
Os métodos são idênticos em todos os aspectos, exceto por uma coisa:
- o método slow usa o arquivo do alimentador não classificado diretamente de
ls -1 -f
- o método rápido usa uma versão classificada do mesmo arquivo não classificado
Não tenho certeza se a classificação é o problema aqui, ou talvez o arquivo do alimentador classificado coincida com a sequência na qual os arquivos foram criados (usei um algoritmo inteiro ascendente simples)
Para 1 milhão de arquivos, o método rápido rm filename
é 60 vezes mais rápido que o lento ... novamente, não sei se é um problema de "classificação" ou um problema de tabela de hash nos bastidores ... suspeito não é uma questão simples de classificação, porque por que ls -1 -f
me forneceria intencionalmente uma lista sem classificação de uma sequência "ordenada" de nomes de arquivos recém-adicionados ...
Só estou me perguntando o que está acontecendo aqui, por isso não levo dias (sim dias) para excluir os próximos 10 milhões de arquivos :) .... Eu digo "dias" porque tentei tantas alternativas, e o os tempos envolvidos aumentam desproporcionalmente ao número de arquivos envolvidos .. então eu só testei 1 milhão em detalhes
BTW: excluir os arquivos por meio da "lista classificada" de nomes é realmente mais rápido que rm -rf
por um fator de 2.
e: rm -r
era 30 vezes mais lento que o método "lista classificada"
... mas está "resolvido" o problema aqui? ou está mais relacionado a um método de armazenamento em hash (ou qualquer outro) usado pelo ext4?
O que me intriga bastante é que cada chamada rm filename
não está relacionada à anterior .. (bem, pelo menos é assim da perspectiva do 'bash')
Estou usando a unidade Ubuntu / bash / 'ext4' / SATA II.
fonte
find -delete
?cat
arquivo simples para um novo antes do 1º teste - em vez desort
antes do 2º teste.Respostas:
Espera-se que rm -r seja lento como recursivo. Um primeiro percurso de profundidade deve ser feito na estrutura de diretórios.
Agora, como você criou 10 milhões de arquivos? você usou algum script que faz um loop em alguma ordem? 1.txt, 2.txt, 3.txt ... se sim, esses arquivos também podem ser alocados na mesma ordem em blocos contíguos no hdd.so excluir na mesma ordem será mais rápido.
"ls -f" ativará -aU, que lista em ordem de diretório, que é novamente recursiva.
fonte
Você deve otimizar a estrutura de arquivos. Então, ao invés de
faça algo mais inteligente como (bash assumido):
Agora, este exemplo é bastante lento por causa do uso de md5sum [1], use algo como o seguinte para obter respostas muito mais rápidas, desde que você não precise de nomes de arquivos específicos, as duplicatas não são motivo de preocupação e não é necessário hash repetível de um determinado nome :)
É claro que tudo isso é um conceito de empréstimo de hashtables
fonte