Como medir o tempo médio de execução de um script?

18

Eu tenho dois scripts que cada um calcula o fatorial de um número. Eu gostaria de saber qual é mais rápido. O comando time me dá milissegundos e o resultado é diferente de tempos em tempos:

piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.089s
user    0m0.052s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.091s
user    0m0.048s
sys 0m0.036s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.088s
user    0m0.048s
sys 0m0.040s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.088s
user    0m0.048s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.087s
user    0m0.064s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.089s
user    0m0.068s
sys 0m0.016s
piousbox@piousbox-laptop:~/projects/trash$ 

Como faço para levar o tempo médio necessário para executar o script? Eu poderia analisar e calcular a saída de umtime de 100%, mas imagino que exista uma solução melhor?

    
por Victor Piousbox 05.06.2013 / 09:10

5 respostas

4

Não, sua ideia de calcular a média está correta.

A execução de scripts depende de vários fatores e, no entanto, deve ser dividida entre o tempo de configuração (carregamento do interpretador na memória, configuração e, possivelmente, compilação do código para bytecode ou código de máquina) e verdadeiro tempo de execução.

Para melhor focar no tempo de execução interno, você faz o loop no próprio script (ou seja, em vez de calcular um fatorial, calcula-o 100 vezes em uma execução do script. O script será configurado uma vez e a rotina interna executará 100 vezes).

Para focar no tempo total, você executa o script cem vezes e calcula a média dos resultados. Idealmente, você deve separar essas execuções o suficiente para que o sistema retorne em um "estado de referência" (ou um estado não relacionado a script) todas as vezes. Por exemplo, o próprio intérprete será armazenado em cache na memória, para que a execução primeira do script seja apreciavelmente mais lenta do que as subsequentes.

Para obter uma visão melhor do algoritmo, acho que a melhor maneira é algo assim (em uma máquina inativa):

  • envolva o algoritmo em uma única função.
  • no aplicativo de controle:
    • chama a função uma vez
    • obtenha o tempo do sistema ("relógio de parede") e adicione 10 (ou um N razoável) segundos
    • insira o loop e comece a contar as iterações
    • após cada chamada para a função, incremente o contador
    • se a hora do sistema estiver abaixo do tempo economizado, faça outro loop
    • obtenha N exato, possivelmente ponto flutuante, do tempo atual do relógio de parede
    • exibe o contador dividido por N: esse é o número de iterações / segundo.

O aplicativo só é executado uma vez, toda a configuração e preparação é feita pela primeira iteração de duração indeterminada, portanto, isso deve minimizar as despesas gerais (exceto talvez para a chamada de horário).

Se a função receber uma entrada, você faria bem em fornecer uma sequência aleatória de entradas usando um PRNG semeado com um valor fixo, para assegurar que ambas as versões da função sendo testada recebam os mesmos valores. Isso evita que uma função seja executada aparentemente melhor devido a "números da sorte" (por exemplo, eu me lembro de uma variação do algoritmo Hillsort que teve melhor desempenho se o número de itens a serem classificados estava na forma 2 k -1 com pequenos k s).

    
por 05.06.2013 / 09:16
32

Você pode executar iterações do programa em um loop; e dividir o tempo total pelo número de iterações:

time for i in {1..10}; do sleep 1; done
real    0m10.052s
user    0m0.005s
sys 0m0.018s
    
por 05.06.2013 / 09:19
9
python -m timeit -n 1 -r 100 -s 'import os' 'os.system("ruby fac1.rb")'

Para -n , -r e outras opções, consulte link

    
por 02.06.2015 / 18:07
6

existe uma ferramenta chamada multitime que faz exatamente isso: executar um comando várias vezes, medindo quanto tempo demora (real / usuário / sistema com tempo médio, mínimo / máximo e mediano computado automaticamente)

Por exemplo, para medir um script semelhante 100 vezes:

multitime -q -n 100 "fact1.sh"
===> multitime results
1: -q fact1.sh
            Mean        Std.Dev.    Min         Median      Max
real        0.122       0.032       0.086       0.116       0.171       
user        0.148       0.044       0.096       0.137       0.223       
sys         0.023       0.019       0.000       0.014       0.061 
    
por 08.03.2018 / 23:32
2

Isso é antigo, mas surgiu muito no google quando eu estava procurando por um comando que eu usei anteriormente, mas não consegui encontrar. De qualquer forma, minha maneira preferida de fazer isso é:

perf stat -r 10 -B sleep 1

Isso fornece alguns detalhes, incluindo o tempo médio de execução no final:

1.002248382 seconds time elapsed                   ( +-  0.01% )
    
por 24.12.2017 / 06:48

Tags