Получить время выполнения программы в оболочке
Я хочу что-то выполнить в оболочке linux в нескольких разных условиях и иметь возможность выводить время выполнения для каждого выполнения.
Я знаю, что я мог бы написать perl или python script, чтобы это сделать, но есть ли способ сделать это в оболочке? (что бывает bash)
Ответы
Ответ 1
Используйте встроенное ключевое слово time
:
$ help time
time: time [-p] PIPELINE
Execute PIPELINE and print a summary of the real time, user CPU time,
and system CPU time spent executing PIPELINE when it terminates.
The return status is the return status of PIPELINE. The `-p' option
prints the timing summary in a slightly different format. This uses
the value of the TIMEFORMAT variable as the output format.
Пример:
$ time sleep 2
real 0m2.009s
user 0m0.000s
sys 0m0.004s
Ответ 2
Вы можете получить гораздо более подробную информацию, чем bash встроенный time
(что упоминает Роберт Гэмбл) с помощью time (1). Обычно это /usr/bin/time
.
Примечание редактора:
Чтобы убедиться, что вы вызываете внешнюю утилиту time
, а не ключевое слово оболочки time
, вызовите ее как /usr/bin/time
.
time
является POSIX-обязательной утилитой, но единственным вариантом, который требуется для поддержки, является -p
.
Конкретные платформы реализуют конкретные нестандартные расширения: -v
работает с утилитой GNU time
, как показано ниже (вопрос помечен linux); в реализации BSD/macOS используется -l
для получения аналогичного результата - см. man 1 time
.
Пример подробного вывода:
$ /usr/bin/time -v sleep 1
Command being timed: "sleep 1"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 1%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 210
Voluntary context switches: 2
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Ответ 3
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
Ответ 4
Для линейного дельта-измерения попробуйте gnonom.
Утилита командной строки, немного подобная moreutils ts, для добавления информации о временной отметке к стандартным выводам другой команды. Полезно для длительных процессов, где вам нужна историческая запись того, что занимает так много времени.
Вы также можете использовать параметры --high
и/или --medium
, чтобы указать порог длины в секундах, по которому gnomon будет выделять метку времени красным или желтым цветом. И вы можете сделать еще несколько вещей.
![example]()
Ответ 5
Если вам нужна более высокая точность, используйте %N
с date
(и используйте bc
для diff, потому что $(())
обрабатывает только целые числа).
Вот как это сделать:
start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)
printf "Execution time: %.6f seconds" $dur
Пример:
start=$(date +%s.%N); \
sleep 0.1s; \
dur=$(echo "$(date +%s.%N) - $start" | bc); \
printf "Execution time: %.6f seconds\n" $dur
Результат:
Execution time: 0.104623 seconds
Ответ 6
Если вы собираетесь использовать время позже для вычисления, узнайте, как использовать параметр -f
для /usr/bin/time
для вывода кода, который экономит время. Здесь некоторый код, который я использовал недавно, чтобы получить и отсортировать время выполнения целой классной программы студентов:
fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...
Позднее я конкатенировал все файлы $timefile
и вывел вывод в интерпретатор Lua. Вы можете сделать то же самое с Python или bash или любым вашим любимым синтаксисом. Мне нравится эта техника.
Ответ 7
Вы можете использовать time
и subshell ()
:
time (
for (( i=1; i<10000; i++ )); do
echo 1 >/dev/null
done
)
Или в той же оболочке {}
:
time {
for (( i=1; i<10000; i++ )); do
echo 1 >/dev/null
done
}
Ответ 8
Если вам нужна только точность во второй, вы можете использовать встроенную переменную $SECONDS
, которая подсчитывает количество секунд, в течение которых была запущена оболочка.
while true; do
start=$SECONDS
some_long_running_command
duration=$(( SECONDS - start ))
echo "This run took $duration seconds"
if some_condition; then break; fi
done
Ответ 9
Способ
$ > g++ -lpthread perform.c -o per
$ > time ./per
вывод →
real 0m0.014s
user 0m0.010s
sys 0m0.002s