Измерять производительность быстрого сценария bash?

В языках программирования я обычно измерял бы производительность чего-то относительно быстрого (& lt; 1-секундное завершение), зацикливая его несколько тысяч раз, а затем получая среднее время на выполнение.

Как бы я сделать то же самое в bash, чтобы сравнить производительность выполнения двух очень быстрых команд?

1
задан 14 May 2017 в 19:51

6 ответов

В общем, простой способ - сделать time ./myscript.sh, но это покажет вам нуль секунду, так как ваш скрипт действительно быстр.

Вместо этого используйте простой способ , которые используют GNU date (возможность отображения наносекунд) и PS4.

0
ответ дан 18 July 2018 в 13:18

Лучше использовать что-то вроде команды time.

У Bash также есть встроенный time, то, что я предлагаю, использует двоичный файл time, расположенный по адресу: /usr/bin/time.

Для одного времени выполнения:

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

Какие выходы:

Elapsed: 0:00.01 User: 0.00 System: 0.00 Memory: 2412 command: заставляет bash использовать /usr/bin/time вместо time встроенный.

Вы можете использовать time с циклом, чтобы получить «avrage», «min», «max» определенного ресурса say memory:

Этот код будет работать ./COMMAND 1000 раз, затем распечатывает «min, max, avg» из его общего объема (данных + стек + текст).

#/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

Вот выход:

2436.89 2524 2324

Вы можете изменить %K на:

command: заставляет bash использовать /usr/bin/time вместо встроенного time. %I: Количество входных файлов %P: процент CPU, который получил это задание %k: количество сигналов, переданных в процесс %U: использование ЦП в пользовательском режиме %S: использование ЦП в режиме ядра

см. man time

Благодаря muru для написания более четкого заявления awk.

3
ответ дан 18 July 2018 в 13:18

Nevermind, получил:

N=10000 time(for i in $(eval echo "{1..$N}"); do ./mycommand &>/dev/null done)
1
ответ дан 18 July 2018 в 13:18

В общем, простой способ - сделать time ./myscript.sh, но это покажет вам нуль секунду, так как ваш скрипт действительно быстр.

Вместо этого используйте простой способ , которые используют GNU date (возможность отображения наносекунд) и PS4.

0
ответ дан 24 July 2018 в 20:09
  • 1
    Пожалуйста, не давайте ссылки в качестве ответов. Вместо этого укажите соответствующую информацию из ссылки и укажите ссылку в качестве ссылки. Здесь, например, вы ссылаетесь на вопрос с несколькими ответами. Какой из них должен использовать OP? Как бы они адаптировали его для своей конкретной проблемы? – terdon♦ 15 May 2017 в 00:38

Лучше использовать что-то вроде команды time.

У Bash также есть встроенный time, то, что я предлагаю, использует двоичный файл time, расположенный по адресу: /usr/bin/time.

Для одного времени выполнения:

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

Какие выходы:

Elapsed: 0:00.01 User: 0.00 System: 0.00 Memory: 2412 command: заставляет bash использовать /usr/bin/time вместо time встроенный.

Вы можете использовать time с циклом, чтобы получить «avrage», «min», «max» определенного ресурса say memory:

Этот код будет работать ./COMMAND 1000 раз, затем распечатывает «min, max, avg» из его общего объема (данных + стек + текст).

#/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

Вот выход:

2436.89 2524 2324

Вы можете изменить %K на:

command: заставляет bash использовать /usr/bin/time вместо встроенного time. %I: Количество входных файлов %P: процент CPU, который получил это задание %k: количество сигналов, переданных в процесс %U: использование ЦП в пользовательском режиме %S: использование ЦП в режиме ядра

см. man time

Благодаря muru для написания более четкого заявления awk.

3
ответ дан 24 July 2018 в 20:09
  • 1
    Это странный способ сделать это ... Вместо echo $(...) | tr ' ' '\n' вы могли бы просто сделать for i in {1..1000}; do command time -f "%K\n" ./COMMAND 2>&1 1>/dev/null; done. И в awk неинициализированные переменные получают значение 0, поэтому awk '$0 < min {min = $0} $0 > max {max = $0} {total += $0} END {print total/NR; max, min}' Команда GNU time также поддерживает ведение журнала в файле -o file, поэтому вы можете использовать его, а затем запустить awk в этом файле позже , вместо перенаправления stderr и stdout – muru 14 May 2017 в 20:47
  • 2
    о, да, min необходимо инициализировать чем-то другим, кроме 0. -v min=foo или NR == 1 {min = $0}. Извини за это – muru 14 May 2017 в 21:36
  • 3
    @muru исправил это;) Еще раз спасибо :-) Gotta learn awk Думаю: D – Ravexina 14 May 2017 в 21:43
  • 4
    Проблема с этим методом заключается в том, что / bin / time использует только centisecond разрешение для CPU, поэтому для очень быстрых команд CPU будет равен нулю. Например, процессор, используемый при запуске sleep .1, округляется до 0.00, поэтому независимо от того, сколько итераций он запускает, общая сумма CPU всегда будет равна нулю. (встроенное время bash имеет миллисекундное разрешение). Кроме того, Истекшее время, напечатанное %E, имеет вид [hours:]minutes:seconds.xxx (то есть 0: 00.11), поэтому вы не можете суммировать его с простым оператором awk +. – Johnny 15 May 2017 в 03:38

Nevermind, получил:

N=10000 time(for i in $(eval echo "{1..$N}"); do ./mycommand &>/dev/null done)
1
ответ дан 24 July 2018 в 20:09
  • 1
    for i in $(seq 1 $N) вместо eval echo будет проще. Или for ((i = 0; i < N; i++)) – muru 14 May 2017 в 20:48
  • 2
    Не используйте eval, он здесь лишний и рекомендуется избегать в целом. Используйте то, что предложил – Sergiy Kolodyazhnyy 14 May 2017 в 21:14

Другие вопросы по тегам:

Похожие вопросы: