shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Desempenho ao checar se string existe em arquivo de t


From: Alfredo Casanova
Subject: Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto
Date: Mon, 05 Jan 2015 20:06:51 +0000

Caraca, acho que foi o reply em que mais aprendi coisas nessa lista até hoje. Valeu, Ronaldo.

On Wed Dec 24 2014 at 3:04:23 PM Ronaldo Ferreira de Lima address@hidden [shell-script] <address@hidden> wrote:

On Tue, Dec 23, 2014 at 11:36:39PM -0200, Fernando Mercês address@hidden [shell-script] wrote:
> Amigos,
> Num script que acabei de fazer [1] tenho um arquivo de texto que é uma lista de
> nomes de usuário (um por linha). E quero checar se eles existem no sistema. Fiz
> deste jeito:
>
> while IFS= read i; do
> grep -qm1 "^$i:" /etc/passwd && echo "$i matches with an existent user. Be careful!"
> done < "$outfile"
>
> Mas este "$outfile" é muito grande. Milhares de linhas e demora um pouco.
> Alguma ideia pra otimizar?

Sim, algumas:

a. associative arrays:
declare -A username
while IFS=$':\n' read user last; do
let "username[$user] += 1"
(( username[$user] > 1 )) && echo $user
done < <(cat /etc/passwd usernames.txt)

b. awk:
awk -F: 'a[$1]++' /etc/passwd usernames.txt

c. grep -f + cut:
grep -x -f <(cut -d: -f1 /etc/passwd) usernames.txt

d. sort+cut+uniq:
sort <(cut -d: -f1 /etc/passwd) usernames.txt|uniq -d

Nos meus testes, 'usernames.txt' é o equivalente ao seu $outfile e é um
arquivo com 1k usernames e apenas 1 existente no /etc/passwd. Assumi
também que não existem duplicidade dentro do $outfile.

Realizei um benchmark com uma ferramenta desenvolvida a princípio para
testar código Perl mas que produz um relatório bem legível:

Benchmarking a => sub { system q(bash associative_array.sh 2&>/dev/null) }, b => sub { system q(bash awk.sh &>/dev/null) }, c => sub { system q(bash grep-f+cut.sh &>/dev/null) }, d => sub { system q(bash sort+cut+uniq.sh &>/dev/null) } ...
Benchmark: timing 1000 iterations of a, b, c, d...
a: 37 wallclock secs ( 0.01 usr 0.13 sys + 32.94 cusr 2.59 csys = 35.67 CPU) @ 28.03/s (n=1000)
b: 7 wallclock secs ( 0.02 usr 0.11 sys + 4.78 cusr 1.29 csys = 6.20 CPU) @ 161.29/s (n=1000)
c: 8 wallclock secs ( 0.01 usr 0.11 sys + 4.91 cusr 1.13 csys = 6.16 CPU) @ 162.34/s (n=1000)
d: 6 wallclock secs ( 0.01 usr 0.11 sys + 3.50 cusr 1.53 csys = 5.15 CPU) @ 194.17/s (n=1000)

O campeão aqui foi o 'sort+cut+uniq'. Não consegui incluir o seu código
nos testes porque demorava muito a conclusão na minha máquina. Ele fica
abaixo de 1/s e fica muito aquém dos outros exemplos.

Como última observação, dependendo do tamanho do /etc/passwd, do
$outfile e da quantidade duplicatas, esses valores podem mudar.



> Grato e feliz natal! :)
> [1] https://gist.github.com/merces/0a4d2272d79d00cc0fe1
> Att,
>
> Fernando Mercês
> Linux Registered User #432779
> www.mentebinaria.com.br
> ------------------------------------
> "Ninguém pode ser escravo de sua identidade; quando surge uma possibilidade de
> mudança é preciso mudar". (Elliot Gould)

[]'s
--
"Não manejo bem as palavras
Mas manipulo bem as strings."
------------------------------
http://tecnoveneno.blogspot.com


reply via email to

[Prev in Thread] Current Thread [Next in Thread]