Como `cronometrar` um comando N vezes (e ser capaz de usar CTRL-C para interrompê-lo)

Como `cronometrar` um comando N vezes (e ser capaz de usar CTRL-C para interrompê-lo)

Pergunta curta:

Isso é feito em um Mac:

time for i in {1..10}; do python3 foo.py ; done

mas CTRL-C não será capaz de pará-lo. Como fazer dar certo? (ou como cronometrar o tempo de execução de N vezes?)


Detalhes:

Existe algum teste padrão de programa no github e eu poderia executá-lo:

 python3 foo.py

ou

 time python3 foo.py

e relata 0,27 segundos de tempo de execução. Como o teste está conectado para 1.000 casos de teste e para uma estrutura de teste, não quero alterar o teste, então quero cronometrar 100 vezes. Parece que o comando timenão tem como cronometrar 10 ou 100 vezes (isso é um tanto estranho para o Unix, que tantos anos e algo tão útil e simples não esteja incorporado time). O seguinte pode ser usado:

time for i in {1..10}; do python3 foo.py ; done

mas CTRL-C não será capaz de pará-lo - ele interromperá aquele script python e continuará executando o resto. Felizmente não foi 100ou 1000foi digitado. Existe uma maneira de usar timeou uma maneira melhor de fazer isso? (além de mudar o programa?)

Responder1

Não é possível, Ctrl-Cpois você está gerando novos processos em loop. Você teria que interromper todos eles pressionando Ctrl-C100, 1000 vezes mais rápido que cada iteração estivesse sendo executada.
Como alternativa, você poderia obter o mesmo efeito bashpressionando Ctrl-Zo que interromperia o último processo de primeiro plano criado pelo loop edesistiro próprio laço.

Responder2

Supondo que o shell seja zsh, basta fazer:

time (repeat 10 python3 foo.py)

Isso cronometra o processo (e esperou pelos filhos) que executa o subshell que executa o comando python3 10 vezes.

Com bashou ksh93(ou zsh), você pode fazer:

time (for ((i=0;i<10;i++)) { python3 foo.py; })

POSIXly, você poderia fazer:

time -p sh -c '
  i=0; while [ "$i" -lt 10 ]; do
    python3 foo.py
    i=$((i + 1))
  done'

Responder3

Não é uma solução "Ctrl + C", mas algo se você quiser interromper "graciosamente" uma sequência de loop longa. Tudo que você precisa fazer é criar ./stop-foo-pyum arquivo; com, $ echo "" > ./stop-foo-pypor exemplo (em outro terminal).

rm ./stop-foo-py
time for ((i=0;i<1000;i++));
    do if [ ! -f "./stop-foo-py" ]; then
        python foo.py ;
        fi ;
    done

ou rm ./stop-foo-py; time for ((i=0;i<1000;i++)); do if [ ! -f "./stop-foo-py" ]; then python foo.py ; fi ; doneem uma linha.

Acrescenta cerca de metadeEMpor loop único.

$ time for ((i=0;i<1000;i++)); do if [ ! -f "./stop" ]; then : ; fi ; done

real    0m0.548s
user    0m0.157s
sys     0m0.359s

informação relacionada