Как использовать команду времени в Linux

Хотите знать, как долго длится процесс, и многое другое? Команда Linux time возвращает статистику времени, давая вам отличное представление о ресурсах, используемых вашими программами.

время имеет много родственников

Существует множество дистрибутивов Linux и различных Unix-подобных операционных систем. У каждого из них есть командная оболочка по умолчанию. Наиболее распространенной оболочкой по умолчанию в современных дистрибутивах Linux является оболочка bash. Но есть много других, таких как оболочка Z (zsh) и оболочка Korn (ksh).

Все эти оболочки включают свою собственную команду времени, либо как встроенный командование или как зарезервированное слово. Когда вы вводите время в окне терминала, оболочка выполнит свою внутреннюю команду вместо использования двоичного файла времени GNU, который предоставляется как часть вашего дистрибутива Linux.

Мы хотим использовать версию времени GNU, потому что в ней больше параметры и более гибкий.

Который раз будет бежать?

Вы можете проверить, какая версия будет запущена, с помощью команды type. type сообщит вам, будет ли оболочка обрабатывать вашу инструкцию самостоятельно со своими внутренними подпрограммами или передать ее двоичному файлу GNU.

в окне терминала введите тип слова, пробел, затем слово «время» и нажмите Enter.

type time

введите время в окне терминала bash

Мы видим, что в оболочке bash время — зарезервированное слово. Это означает, что Bash по умолчанию будет использовать свои внутренние процедуры времени.

type time

введите время в окне терминала zsh

В оболочке Z (zsh) время — зарезервированное слово, поэтому по умолчанию будут использоваться внутренние процедуры оболочки.

type time

введите время в окне оболочки Korn

В оболочке Korn время — ключевое слово. Вместо команды времени GNU будет использоваться внутренняя процедура.

Запуск команды времени GNU

Если оболочка в вашей системе Linux имеет внутреннюю подпрограмму времени, вам нужно будет явно указать, если вы хотите использовать двоичный файл времени GNU. Вы должны либо:

Укажите полный путь к двоичному файлу, например / usr / bin / time. Запустите команду which time, чтобы найти этот путь.
Используйте командное время.
Используйте обратную косую черту, например время.

  Как установить Linux с телефона Android с помощью DriveDroid

вывод команды time в окне терминала

Команда which time дает нам путь к двоичному файлу.

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

Ввод команды time также работает, и время от времени мы получаем ту же информацию об использовании. Команда command указывает оболочке игнорировать следующую команду, чтобы она обрабатывалась вне оболочки.

Использование символа перед именем команды аналогично использованию команды перед именем команды.

Самый простой способ убедиться, что вы используете двоичный файл времени GNU, — это использовать опцию обратной косой черты.

time
time

время и вывод времени в окне терминала

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

Использование команды времени

Приведем время для некоторых программ. Мы используем две программы, называемые loop1 и loop2. Они были созданы из loop1.c и loop2.c. Они не делают ничего полезного, кроме демонстрации эффектов одного типа неэффективности кодирования.

Это loop1.c. Длина строки требуется в двух вложенных циклах. Длина получается заранее, вне двух вложенных петель.

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main (int argc, char* argv[])
{
 int i, j, len, count=0;
 char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek";

 // get length of string once, outside of loops
 len = strlen( szString );  

 for (j=0; j

This is loop2.c. The length of the string is obtained time after time for every cycle of the outer loop. This inefficiency ought to show up in the timings.

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main (int argc, char* argv[])
{
 int i, j, count=0;
 char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek";

 for (j=0; j

Let’s fire up the loop1 program and use time to measure its performance.

time ./loop1

время результатов для цикла 1 в окне терминала

Теперь сделаем то же самое для loop2.

time ./loop2

вывод времени для цикла 2 в окне терминала

Это дало нам два набора результатов, но они в очень уродливом формате. Мы можем что-то с этим сделать позже, но давайте выберем несколько кусочков информации из результатов.

При запуске программы есть два режима выполнения, между которыми они переключаются. Они называются пользовательским режимом и режимом ядра.

Короче говоря, процесс в пользовательском режиме не может напрямую обращаться к оборудованию или ссылочной памяти за пределами своего собственного распределения. Чтобы получить доступ к таким ресурсам, процесс должен делать запросы к ядру. Если ядро ​​одобряет запрос, процесс переходит в режим ядра до тех пор, пока требование не будет удовлетворено. Затем процесс возвращается к выполнению в пользовательском режиме.

Результаты для loop1 говорят нам, что loop1 провел 0,09 секунды в пользовательском режиме. Либо он провел нулевое время в режиме ядра, либо время в режиме ядра слишком низкое для регистрации после округления в меньшую сторону. Общее затраченное время составило 0,1 секунды. loop1 было выделено в среднем 89% процессорного времени на протяжении всего прошедшего времени.

Неэффективная программа loop2 выполнялась в три раза дольше. Его общее затраченное время составляет 0,3 секунды. Длительность обработки в пользовательском режиме составляет 0,29 секунды. Ничего не регистрируется для режима ядра. loop2 было выделено в среднем 96% процессорного времени за время его выполнения.

Форматирование вывода

Вы можете настроить вывод времени, используя строку формата. Строка формата может содержать спецификаторы текста и формата. Список спецификаторов формата может быть найдено на странице руководства На время. Каждый из спецификаторов формата представляет собой часть информации.

Когда строка печатается, спецификаторы формата заменяются фактическими значениями, которые они представляют. Например, спецификатором формата для процента использования ЦП является буква P. Чтобы указать времени, что описатель формата - это не просто обычная буква, добавьте к нему знак процента, например% P. Воспользуемся этим в качестве примера.

Параметр -f (строка формата) используется для указания времени, что то, что следует далее, является строкой формата.

Наша строка формата будет печатать символы «Программа:» и имя программы (и любые параметры командной строки, которые вы передаете программе). Спецификатор формата% C означает «Имя и аргументы командной строки синхронизируемой команды». N переводит вывод на следующую строку.

Существует множество спецификаторов форматов, и они чувствительны к регистру, поэтому убедитесь, что вы вводите их правильно, когда делаете это для себя.

Затем мы собираемся напечатать символы «Общее время:», за которыми следует значение общего времени, прошедшего для этого запуска программы (представленного% E).

Мы используем n, чтобы дать еще одну новую строку. Затем мы напечатаем символы «User Mode (s)», за которыми следует значение времени процессора, проведенного в пользовательском режиме, обозначенное% U.

Мы используем n, чтобы дать еще одну новую строку. На этот раз мы готовимся к значению времени ядра. Мы печатаем символы «Kernel Mode (s)», за которыми следует спецификатор формата для времени процессора, затраченного на режим ядра, то есть% S.

Наконец, мы собираемся напечатать символы «nCPU:», чтобы получить новую строку и заголовок для этого значения данных. Спецификатор формата% P даст средний процент процессорного времени, используемого синхронизированным процессом.

Вся строка формата заключена в кавычки. Мы могли бы включить несколько символов t для размещения вкладок в выводе, если бы мы были озабочены выравниванием значений.

time -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1

Вывод из строки формата для loop1 в окне терминала

Отправка вывода в файл

Чтобы вести учет таймингов проведенных вами тестов, вы можете отправлять результаты по времени в файл. Для этого используйте параметр -o (вывод). Вывод вашей программы по-прежнему будет отображаться в окне терминала. В файл перенаправляется только вывод времени.

Мы можем повторно запустить тест и сохранить результат в файле test_results.txt следующим образом:

time -o test_results.txt -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1
cat test_results.txt

Вывод из строки формата для loop1 передан в файл в окне терминала

Выходные данные программы loop1 отображаются в окне терминала, а результаты со временем переходят в файл test_results.txt.

Если вы хотите сохранить следующий набор результатов в том же файле, вы должны использовать параметр -a (добавить) следующим образом:

time -o test_results.txt -a -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop2
cat test_results.txt

Вывод из строки формата для loop2, добавленной к файлу в окне терминала

Теперь должно быть очевидно, почему мы использовали спецификатор формата% C, чтобы включить имя программы в вывод из строки формата.

И у нас нет времени

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