@ A resposta de Stéphane Chazelas fornece muitos detalhes sobre como você pode otimizar o pipeline de comando
find . -name "muc*_*_20160920_*.unl*" | xargs zcat |
awk -F "|" '{if($14=="20160920100643" && $22=="567094398953") print $0}'| head
Vou fornecer outra maneira de abordar o problema em que você realmente mede onde está gastando mais tempo. Depois de descobrir onde o tempo é gasto, você pode determinar o que fazer a respeito. Se você quer melhorar seu tempo de execução de 10 minutos, otimizar um passo que leva 2 segundos é quase inútil.
Quando olho para o pipeline de comando, três coisas chamam minha atenção:
-
find .
- Como é a estrutura de diretórios? Quantos arquivos por
diretório? O diretório é local para o sistema no qual o comando está sendo executado? Um sistema de arquivos remoto será muito mais lento.
-
-name "muc*_*_20160920_*.unl*"
- Quão perto estão todos
nomes de arquivos na estrutura de diretórios? Eles estão todos "próximos" do
nome e difícil / CPU intensivo para combinar? Porque todos os arquivos
a árvore de diretórios tem que ter seu nome lido do disco e comparado
para o padrão.
-
xargs zcat
- O xargs
não parece ser um problema de desempenho, especialmente em comparação com os problemas de find
acima e com o zcat
em si. Mesmo se forem 10.000 ou 10.000.000 nomes de arquivos, o tempo usado para passar e analisar apenas os nomes é quase certamente insignificante comparado ao tempo gasto encontrando os nomes e então abrindo e descompactando todos os arquivos. Quão grandes são os arquivos? Porque você está descomprimindo o
todos os arquivos todos que correspondem ao nome do arquivo find
padrão.
Como você pode determinar qual é o maior problema de desempenho? Meça o desempenho de cada comando no pipeline. (Consulte o link para obter detalhes sobre o tempo de duração de todo o pipeline.) execute os seguintes comandos e veja quanto tempo cada etapa contribui para o tempo de processamento de todo o pipeline:
/usr/bin/time find .
- Isso informa quanto tempo leva para percorrer sua árvore de diretórios. Se isso for lento, você precisa de um sistema de armazenamento melhor. Descarregue seu cache do sistema de arquivos [s ] antes de sincronizar isso para obter uma medição de pior caso, execute o find
cronometrado novamente e veja quanto o armazenamento em cache afeta o desempenho. E se o diretório não for local, tente executar o comando no sistema real em que os arquivos estão.
/usr/bin/time find . -name "muc*_*_20160920_*.unl*"
- Isso informará quanto tempo leva para combinar os nomes dos arquivos. Novamente, libere o cache do sistema de arquivos [s] e execute-o duas vezes.
/usr/bin/time bash -c "find . -name 'muc*_*_20160920_*.unl*' | xargs zcat > /dev/null"
- Este é o que eu suspeito ser o principal componente do longo tempo de execução do seu pipeline. Se este for o problema, paralelizar os comandos zcat
por resposta de Stéphane Chazelas pode ser a melhor resposta.
Continue adicionando etapas do pipeline de comando original ao que está sendo testado até descobrir onde você está gastando a maior parte do tempo. Novamente, suspeito que seja a etapa zcat
. Se assim for, talvez a zcat
de paralelização que @ Stéphane Chazelas postou ajudará.
Paralelizar zcat
pode não ajudar - pode até prejudicar o desempenho e diminuir o processamento. Com apenas um zcat
sendo executado por vez, o IO pode estar em um bom padrão de fluxo que minimiza as pesquisas de disco. Com vários processos de zcat
sendo executados de uma só vez, as operações de E / S podem competir e realmente retardar o processamento, pois as cabeças de disco precisam procurar e qualquer leitura antecipada feita se torna menos eficaz.
Se a etapa zcat
for o seu principal gargalo de desempenho e a execução de vários processos zcat
de uma só vez não ajudar ou realmente atrapalhar você, seu pipeline será vinculado a E / S e você precisará resolver o problema usando armazenamento mais rápido.
E novamente - se o diretório não for local na máquina em que você está executando o pipeline de comando, tente executá-lo na máquina em que o sistema de arquivos realmente está.