Как рассчитать время выполнения команды N раз (и иметь возможность остановить ее с помощью CTRL-C)

Как рассчитать время выполнения команды N раз (и иметь возможность остановить ее с помощью CTRL-C)

Короткий вопрос:

Это делается на Mac:

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

но CTRL-C не сможет остановить его. Как заставить его работать? (или как засечь время выполнения N раз?)


Подробности:

Есть стандартная тестовая программа с github, и я могу ее запустить:

 python3 foo.py

или

 time python3 foo.py

и он сообщает о времени выполнения 0,27 секунды. Поскольку тест привязан к 1000 тестовых случаев и к тестовой среде, я не хочу менять тест, поэтому я хочу засечь время 100 раз. Кажется, команда timeне может засечь время 10 или 100 раз (это несколько странно для Unix, что столько лет и что-то такое полезное и простое не встроено в time). Можно использовать следующее:

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

но CTRL-C не сможет остановить его -- он остановит этот один скрипт python и продолжит выполнение остальных. Так что, к счастью, это не было 100или 1000это было введено. Есть ли способ использовать timeили лучший способ сделать это? (кроме изменения программы?)

решение1

Это невозможно, Ctrl-Cтак как вы создаете новые процессы в цикле. Вам пришлось бы прерывать их все, нажимая Ctrl-C100, 1000 раз быстрее, чем выполняется каждая итерация.
В качестве альтернативы вы могли бы достичь того же эффекта, bashнажав Ctrl-Z, что остановило бы последний процесс переднего плана, созданный циклом ипокидатьсам цикл.

решение2

Предполагая, что оболочка — zsh, просто выполните:

time (repeat 10 python3 foo.py)

Это время затрачивается на процесс (и ожидание дочерних процессов), который запускает подоболочку, запускающую команду python3 10 раз.

С помощью bashor ksh93(или zsh) вы можете сделать:

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

В POSIX вы можете сделать следующее:

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

решение3

Это не решение "Ctrl+C", но что-то, если вы хотите "изящно" остановить длинную последовательность циклов. Все, что вам нужно сделать, это создать ./stop-foo-pyфайл; $ echo "" > ./stop-foo-pyнапример, с помощью (в другом терминале).

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

или rm ./stop-foo-py; time for ((i=0;i<1000;i++)); do if [ ! -f "./stop-foo-py" ]; then python foo.py ; fi ; doneв одну строку.

Это добавляет около половиныРСза одну петлю.

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

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

Связанный контент