Eu tenho dois scripts que calculam cada fatorial de um número. Eu gostaria de saber qual é mais rápido. O time
comando fornece 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 levo o tempo médio necessário para executar o script? Eu poderia analisar e calcular a média da saída de 100 time
, mas imagino que exista uma solução melhor?
Respostas:
Não, sua ideia de calcular a média está correta.
A execução do script depende de muitos 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 de código em código de código ou máquina) e o tempo de execução real.
Para focar melhor no tempo de execução interno, faça o loop no próprio script (ou seja, em vez de calcular um fatorial, você o calcula 100 vezes em uma execução do script. O script será configurado uma vez e a rotina interna executará 100 vezes).
Para se concentrar 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 sempre em um "estado de referência" (ou em um estado não relacionado a scripts). Por exemplo, o próprio intérprete será armazenado em cache na memória, para que a primeira execução do script seja sensivelmente mais lenta que as subsequentes.
Para ter uma ideia melhor do algoritmo, acho que a melhor maneira é algo assim (em uma máquina ociosa):
O aplicativo é executado apenas uma vez, toda a configuração e preparação é feita pela primeira iteração temporizada, portanto, isso deve minimizar as despesas gerais (exceto talvez a chamada de tempo).
Se a função receber uma entrada, convém fornecer uma sequência aleatória de entradas usando um PRNG semeado com um valor fixo, para garantir que ambas as versões da função sendo testada recebam os mesmos valores. Isso evita que uma função tenha um desempenho aparentemente melhor devido a "números da sorte" (por exemplo, lembro-me de uma variação do algoritmo Hillsort que teve um desempenho mensurável melhor se o número de itens a serem classificados estivesse no formato 2 k -1 com pequenos k s).
fonte
Você pode executar iterações do programa em um loop; e divida o tempo total pelo número de iterações:
fonte
{1..10}
antes e estou confuso que funcione, não consigo encontrá-lo no manual do bash. O mais triste é que você não conhece a propagação dos seus resultados (tempo mínimo e máximo).man -P 'less +/Brace\ Expansion' bash
bash
. Tente executar/bin/bash
antes disso.existe uma ferramenta chamada multitime que faz exatamente isso: executar um comando várias vezes, medindo quanto tempo leva (real / usuário / sistema com tempo médio, mínimo / máximo e mediano calculado automaticamente)
Por exemplo, para medir um script semelhante 100 vezes:
fonte
Isso é antigo, mas surgiu tão alto no google quando eu estava procurando por um comando que usei anteriormente, mas não consegui encontrar. De qualquer forma, minha maneira preferida de fazer isso é:
Isso fornece muitos detalhes, incluindo o tempo médio de execução no final:
fonte
Para
-n
,-r
e outras opções ver https://docs.python.org/2/library/timeit.html#command-line-interfacefonte
Hyperfine é outra opção.
Uso da amostra:
fonte