Como tornar esta pesquisa mais rápida em fgrep / Ag?

6

Estou pensando em métodos para tornar a pesquisa mais rápida e / ou melhor, que usa principalmente fgrep ou ag . Código que pesquisa a palavra and sem distinção entre maiúsculas e minúsculas em $HOME e redireciona uma lista de correspondências para vim

find -L $HOME -xtype f -name "*.tex" \
   -exec fgrep -l -i "and" {} + 2>/dev/null | vim -R -

É mais rápido com ag devido ao paralelismo e ack

find -L $HOME -xtype f -name "*.tex" \
   -exec ag -l -i "and" {} + 2>/dev/null | vim -R -

Estatísticas

Estatísticas médias de grupos pequenos com fgrep e ag por time

        fgrep   ag     terdon1  terdon2  terdon3  muru 
user    0.41s   0.32s  0.14s    0.22s    0.18s    0.12s
sys     0.46s   0.44s  0.26s    0.28s    0.30s    0.32s

Os casos terdon1 e terdon3 podem ser iguais rapidamente. Eu tenho grandes flutuações com esses dois. Algum Ranking por sys tempo (não é o melhor critério!)

  1. terdon1
  2. terdon2
  3. terdon3
  4. muru
  5. ag
  6. fgrep

Abreviações

  • terdon1 = terdon-muitos-encontrar-grep
  • terdon2 = ter-muitos-encontrar-fgrep
  • terdon3 = terdon-many-find-ag (sem F porque não existe em ag )

Outros códigos

proposta de muru nos comentários

grep -RFli "and" "$HOME" --include="*.tex" | vim -R -

OS: Debian 8.5
Hardware: Asus Zenbook UX303UA

    
por Léo Léopold Hertz 준영 24.12.2016 / 13:35

2 respostas

4

Você provavelmente poderia torná-lo um pouco mais rápido executando várias chamadas find em paralelo. Por exemplo, primeiro obtenha todos os diretórios de nível superior e execute N localizar chamadas, uma para cada diretório. Se você executar o em um subshell, você pode coletar o resultado e passá-lo para o vim ou qualquer outra coisa:

shopt -s dotglob ## So the glob also finds hidden dirs
( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done
) | vim -R -

Ou, para ter certeza, você só começa a receber a saída quando todas as descobertas tiverem terminado:

( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done; wait
) | vim -R -

Eu fiz alguns testes e a velocidade para o acima foi de fato um pouco mais rápida do que o único find . Em média, mais de 10 execuções, a única ferramenta de chamada find 0.898 segundos e a subshell acima executando uma procura por dir demorou 0.628 segundos.

Suponho que os detalhes sempre dependerão de quantos diretórios você tem em $HOME , quantos deles podem conter .tex arquivos e quantos podem corresponder, portanto, sua milhagem pode variar.

    
por 24.12.2016 / 14:15
6

Como você está usando ack e o Silver Searcher ( ag ), parece que está tudo bem em usar ferramentas adicionais.

Uma nova ferramenta neste espaço é ripgrep ( rg ). Ele foi projetado para ser rápido em ambos os arquivos encontrar para pesquisar (como ag ) e também rapidamente em arquivos procurando (como o antigo GNU grep ). / p>

Para o exemplo da sua pergunta, você pode usar algo assim:

rg --files-with-matches --glob "*.tex" "and" "$HOME"

O autor de ripgrep publicou uma análise detalhada de como as diferentes ferramentas de pesquisa funcionam, juntamente com as comparações de referência.

Uma das referências, linux-literal-casei , é um pouco semelhante à tarefa que você descreve. Ele pesquisa um grande número de arquivos em vários diretórios aninhados (a base de código do Linux), procurando por um literal de string que não diferencia maiúsculas e minúsculas.

Nesse benchmark, rg foi mais rápido ao usar uma lista branca (como seu exemplo "* .tex"). A ferramenta ucg também se saiu bem neste benchmark.

rg (ignore)         0.345 +/- 0.073 (lines: 370)
rg (ignore) (mmap)  1.612 +/- 0.011 (lines: 370)
ag (ignore) (mmap)  1.609 +/- 0.015 (lines: 370)
pt (ignore)        17.204 +/- 0.126 (lines: 370)
sift (ignore)       0.805 +/- 0.005 (lines: 370)
git grep (ignore)   0.343 +/- 0.007 (lines: 370)
rg (whitelist)      0.222 +/- 0.021 (lines: 370)+
ucg (whitelist)     0.217 +/- 0.006 (lines: 370)* 

* - Best mean time. + - Best sample time.

O autor excluiu ack dos benchmarks porque era muito mais lento que os outros.

    
por 25.12.2016 / 01:09