Medir o desempenho de um script rápido?

1

Em linguagens de programação, eu normalmente mediria o desempenho de algo relativamente rápido (< 1 segunda conclusão) fazendo um loop de alguns milhares de vezes, e então obtendo o tempo médio por conclusão.

Como eu faria o mesmo no bash para comparar o desempenho de execução de dois comandos muito rápidos?

    
por Tiago 14.05.2017 / 18:51

4 respostas

3

É melhor usar algo parecido com o comando time .

Bash também possui time embutido, o que estou sugerindo é usar time binário localizado em: /usr/bin/time .

Para um tempo de execução:

command time -f "\nElapsed: %E \nUser: %U \nSystem: %S \nMemory: %M\n" \
./MyCommand 1> /dev/null

Quais resultados:

Elapsed: 0:00.01 
User: 0.00 
System: 0.00 
Memory: 2412
  • command : força o bash a usar /usr/bin/time em vez de time interno.

Você pode usar time com um loop para obter uma "avrage", "min", "max" de um recurso específico como memória:

Este código executará ./COMMAND comandos 1000 vezes e, em seguida, imprimirá o "min, max, avg" de seu uso de memória total (dados + pilha + texto).

#/bin/bash
tmpfile='mktemp'
for i in {1..1000}; do  command time -ao $tmpfile -f "%K" ./COMMAND 1>/dev/null; done;
awk 'NR == 1 {min = $0} $0 > max {max = $0} {total += $0} END {print total/NR, min, max}' $tmpfile
rm $tmpfile

Aqui está a saída:

2436.89 2524 2324

Você pode alterar %K com:

  • %E : tempo real decorrido
  • %I : Número de entradas de arquivo
  • %P : Porcentagem da CPU que esse trabalho recebeu
  • %k : Número de sinais entregues ao processo
  • %U : uso da CPU no modo de usuário
  • %S : uso da CPU no modo kernel

veja man time

Obrigado ao muru por escrever uma declaração awk mais clara.

    
por Ravexina 14.05.2017 / 19:42
2

Você pode usar o módulo timeit do Python (que normalmente é usado para trechos de código python), com a função subprocess.call para executar comandos externos:

$ python3 -m timeit -s 'import subprocess' 'subprocess.call(["sleep", "0.1"])' 
10 loops, best of 3: 103 msec per loop

Você pode alterar o número de loops com -n :

$ python3 -m timeit -n 5 -s 'import subprocess' 'subprocess.call(["sleep", "0.1"])' 
5 loops, best of 3: 103 msec per loop

E como sleep 0.1 deve dormir por 100 ms, parece que a medida é bastante precisa.

Veja também:

por muru 14.05.2017 / 19:54
1

Deixa pra lá, entendi:

N=10000
time(for i in $(eval echo "{1..$N}"); do
./mycommand &>/dev/null
done)
    
por Tiago 14.05.2017 / 18:54
0

Em geral, a maneira fácil é fazer time ./myscript.sh , mas isso mostrará zero segundo, pois seu script é realmente rápido.

Em vez disso, use esta resposta que usa o GNU date (capaz de mostrar nanossegundos) e PS4 .

    
por noraj 14.05.2017 / 19:00