Универсальная альтернативная альтернатива non-bash `time`?

Для сравнения времени выполнения скриптов между различными оболочками некоторые ответы на SE предлагают использовать встроенную команду time bash , например:

 time bash -c 'foo.sh' time dash -c 'foo.sh' 

… и т. д. , для проверки каждой оболочки. Такие тесты не позволяют устранить время, затрачиваемое на загрузку и инициализацию каждой оболочки. Например, предположим, что обе приведенные выше команды были сохранены на медленном устройстве со скоростью чтения ранней дискеты , dash ( ~ 150 КБ ) будет загружаться примерно на 7 раз быстрее, чем bash ( ~ 1M ), время загрузки оболочки исказило бы time числа – время предварительной загрузки этих оболочек не имеет значения для измерения времени выполнения foo.sh под каждой оболочкой после загрузки оболочек.

Какая лучшая портативная и общая утилита запускается для сценариев, которые могут запускаться изнутри каждой оболочки? Таким образом, приведенный выше код будет выглядеть примерно так:

 bash -c 'general_timer_util foo.sh' dash -c 'general_timer_util foo.sh' 

NB: нет встроенных команд time , поскольку ни один из них не является переносным или общим.


Еще лучше, если утилита также может сравнить время, затраченное внутренними командами и конвейерами оболочки, без необходимости сначала обернуть их в скрипт. Искусственный синтаксис, подобный этому, поможет:

 general_timer_util "while read x ; do echo x ; done < foo" 

Некоторое время работы снарядов может справиться с этим. Например, bash -c "time while false ; do : ; done" works.

5 Solutions collect form web for “Универсальная альтернативная альтернатива non-bash `time`?”

Следует отметить, что time задано POSIX , а AFAICT – единственный параметр, который POSIX упоминает ( -p ), правильно поддерживается различными оболочками:

 $ bash -c 'time -p echo' real 0.00 user 0.00 sys 0.00 $ dash -c 'time -p echo' real 0.01 user 0.00 sys 0.00 $ busybox sh -c 'time -p echo' real 0.00 user 0.00 sys 0.00 $ ksh -c 'time -p echo' real 0.00 user 0.00 sys 0.00 

Утилита time обычно встроена в оболочку, как вы заметили, что делает ее бесполезной как «нейтральный» таймер.

Однако утилита обычно также доступна в качестве внешней утилиты /usr/bin/time , которая может быть использована для выполнения выбранных вами временных экспериментов.

 $ bash -c '/usr/bin/time foo.sh' 

Я использую команду date GNU , которая поддерживает таймер с высоким разрешением:

 START=$(date +%s.%N) # do something ####################### "$@" &> /dev/null ####################################### END=$(date +%s.%N) DIFF=$( echo "scale=3; (${END} - ${START})*1000/1" | bc ) echo "${DIFF}" 

И затем я вызываю сценарий следующим образом:

 /usr/local/bin/timing dig +short unix.stackexchange.com 141.835 

Выходной блок находится в миллисекундах.

Вот решение, которое:

  1. исключить [s] время, затрачиваемое на загрузку и инициализацию каждой оболочки

  2. может запускаться изнутри каждой оболочки

  3. Пользы

    нет встроенных команд time , поскольку ни один из них не является переносным или общим

  4. Работает во всех POSIX-совместимых оболочках.
  5. Работает на всех совместимых с POSIX и совместимых с XSI системах с компилятором C или где вы можете скомпилировать исполняемый файл C заранее.
  6. Использует ту же временную реализацию для всех оболочек.

Есть две части: короткая программа на C, которая завершает gettimeofday , которая устарела, но еще более переносима, чем clock_gettime , и короткий сценарий оболочки, который использует эту программу, чтобы получить микросекундные часы с точностью до двух сторон поиска сценария. Программа C – это единственный переносимый и минимально-накладной способ получения подсеточной точности в метке времени.

Вот C-программа epoch.c :

 #include <sys/time.h> #include <stdio.h> int main(int argc, char **argv) { struct timeval time; gettimeofday(&time, NULL); printf("%li.%06i", time.tv_sec, time.tv_usec); } 

И timer сценария оболочки:

 #!/bin/echo Run this in the shell you want to test START=$(./epoch) . "$1" END=$(./epoch) echo "$END - $START" | bc 

Это стандартный командный язык командной оболочки и bc и должен работать как скрипт под любой совместимой с POSIX оболочкой.

Вы можете использовать это как:

 $ bash timer ./test.sh .002052 $ dash timer ./test.sh .000895 $ zsh timer ./test.sh .000662 

Он не измеряет системное или пользовательское время, а только время, не прошедшее монотонное время настенных часов. Если системные часы меняются во время выполнения скрипта, это даст неверные результаты. Если система находится под нагрузкой, результат будет ненадежным. Я не думаю, что что-то лучше может быть переносимым между снарядами.

Измененный таймер может использовать eval для запуска команд вне сценария.

Решение с использованием /proc/uptime и awk :

 #!/bin/sh # measure current timestamp (seconds since system start as a float) before=$(awk '{ print $1 }' /proc/uptime) # do something… sleep 2 # subtract timestamps duration=$(awk '{ print $1-'"$before"' }' /proc/uptime) echo "It took $duration seconds." 
  • Какой может быть вариант изменения измененного времени файла в будущем?
  • Временная метка оборудования с использованием PTP
  • touch и tar из текстового файла
  • Копирование только новых файлов
  • Список файлов с момента времени X до времени Y
  • Что вы можете сделать с файлом без запуска отметки «Изменить»?
  • Возможно ли обновлять измененные времена только без копирования файлов при использовании rsync?
  • Удалить последний измененный файл
  • Добавление метки времени в файл журнала с помощью команды cronjob
  • Каков наиболее эффективный способ добавления миллисекунд к этому коду?
  • Сравнение времени файла в ksh
  • Linux и Unix - лучшая ОС в мире.