Por que xargs -n 1 é tão lento para linhas longas

1

Uma linha gerada com o comando echo {,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·} contém 8191 palavras, que são 114687 caracteres: 106497 pontos e 8190 espaços.

Por que dividir com | xargs -n 1 leva eras computacionais? No meu PC são 8 segundos.

História de fundo.

Brincando com a expansão do bracelete bash Eu me deparei com um problema extravagante. Eu estava verificando o tempo de expansão da chave bash no problema de exemplo: imprime strings de um, dois e assim por diante até 'n' (= 13) pontos cada em uma nova linha evitando loops e variáveis explícitos. Eu criei esta solução um tanto lenta:

$ time echo {,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·} | xargs -n 1 | sort -u
·
··
···
····
·····
······
·······
········
·········
··········
···········
············
·············

real    0m8.800s
user    0m0.188s
sys     0m0.748s

Presumi que foi causado por sort performance, por isso, verifiquei uma solução sem ordenar:

$ time echo {,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·} | xargs -n 1 | awk '{if (!a[$0]) {print $0} ; a[$0]=$0}'
·
··
···
····
·····
······
·······
········
·········
··········
···········
············
·············

real    0m8.250s
user    0m0.152s
sys     0m0.784s

O que foi um pouco mais rápido. A expansão em si foi surpreendentemente rápida:

time echo {,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·} > /dev/null

real    0m0.024s
user    0m0.020s
sys     0m0.004s

Foi 0m0.250s ao imprimir parede de pontos para consolar, mas essa é a saída que normalmente é lenta comparada com a computação. Então, verifiquei quanto tempo a divisão de linhas leva:

time echo {,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·}{,·} | xargs -n 1 > /dev/null 

real    0m8.551s
user    0m0.096s
sys     0m0.724s

O que é xargs fazendo todo esse tempo?

    
por Krzysztof Jabłoński 28.12.2016 / 18:18

1 resposta

6

xargs é lento, porque é executado /bin/echo 8191 vezes.

Use | tr -s " " "\n" em vez disso.

    
por 28.12.2016 / 18:26

Tags