Як використовувати команду time в Linux

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

час має багато родичів

Існує багато дистрибутивів Linux і різних Unix-подібних операційних систем. Кожен з них має командну оболонку за замовчуванням. Найпоширенішою оболонкою за замовчуванням в сучасних дистрибутивах Linux є оболонка bash. Але є багато інших, наприклад оболонка Z (zsh) і оболонка Korn (ksh).

Усі ці оболонки включають власну команду часу, або як a вбудований команда або як a зарезервовано слово. Коли ви вводите час у вікні терміналу, оболонка виконає свою внутрішню команду замість того, щоб використовувати двійковий файл часу GNU, який надається як частина вашого дистрибутива Linux.

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

О котрій годині буде бігати?

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

у вікні терміналу введіть тип слова, пробіл, а потім слово час і натисніть Enter.

type time

Ми бачимо, що в оболонкі bash час є зарезервованим словом. Це означає, що Bash буде використовувати свої підпрограми внутрішнього часу за замовчуванням.

type time

В оболонці Z (zsh) час є зарезервованим словом, тому за замовчуванням використовуватимуться внутрішні підпрограми оболонки.

type time

В оболонці Korn час є ключовим словом. Замість команди GNU time буде використовуватися внутрішня процедура.

Запуск команди GNU time

Якщо оболонка у вашій системі Linux має внутрішню підпрограму часу, вам потрібно буде чітко вказати, якщо ви хочете використовувати двійковий файл часу GNU. Ви повинні або:

Надайте повний шлях до двійкового файлу, наприклад /usr/bin/time. Виконайте команду which time, щоб знайти цей шлях.
Використовуйте командний час.
Використовуйте зворотну косу риску, як час.

  Як встановити тему значків Oranchelo на Linux

Команда which time дає нам шлях до двійкового файлу.

Ми можемо перевірити це, використовуючи /usr/bin/time як команду для запуску двійкового файлу GNU. Це працює. Ми отримуємо відповідь від команди time, яка повідомляє, що ми не надали жодних параметрів командного рядка, щоб вона могла працювати.

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

Використання символу перед назвою команди те саме, що використання команди перед назвою команди.

Найпростіший спосіб переконатися, що ви використовуєте двійковий файл часу GNU, це використовувати опцію зворотної косої риски.

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

Тепер зробимо те ж саме для loop2.

time ./loop2

Це дало нам два набори результатів, але вони в дійсно потворному форматі. Ми можемо щось зробити з цим пізніше, але давайте виберемо кілька частин інформації з результатів.

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

Коротше кажучи, процес у режимі користувача не може отримати прямий доступ до апаратної чи контрольної пам’яті за межами свого власного розподілу. Щоб отримати доступ до таких ресурсів, процес повинен робити запити до ядра. Якщо ядро ​​схвалює запит, процес переходить до виконання в режимі ядра, доки вимога не буде задоволена. Потім процес повертається до виконання в режимі користувача.

Результати для loop1 говорять нам, що loop1 провів 0,09 секунди в режимі користувача. Він або провів нуль часу в режимі ядра, або час у режимі ядра є занадто низьким значенням, щоб його зареєструвати після округлення в меншу сторону. Загальний час становив 0,1 секунди. loop1 отримав в середньому 89% часу процесора за весь час, що минув.

Виконання неефективної програми loop2 зайняло втричі більше часу. Його загальний час становить 0,3 секунди. Тривалість часу обробки в режимі користувача становить 0,29 секунди. Нічого не реєструється в режимі ядра. loop2 отримував у середньому 96% часу процесора за час його виконання.

Форматування виводу

Ви можете налаштувати вихід за часом за допомогою рядка форматування. Рядок форматування може містити текст і специфікатори формату. Список специфікаторів формату може бути знайдено на сторінці man на час. Кожен із специфікаторів формату являє собою частину інформації.

Коли рядок друкується, специфікатори формату замінюються фактичними значеннями, які вони представляють. Наприклад, специфікатором формату для відсотка ЦП є буква P. Щоб вказати часу, що специфікатор формату — це не просто звичайна літера, додайте до нього знак відсотка, наприклад %P . Давайте використаємо це на прикладі.

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

Наш форматний рядок буде надрукувати символи «Програма:» і назву програми (і будь-які параметри командного рядка, які ви передаєте програмі). Специфікатор формату %C означає "Ім'я та аргументи командного рядка команди, що фіксується". n призводить до переміщення результату до наступного рядка.

Існує багато специфікаторів форматів, і вони чутливі до регістру, тому переконайтеся, що ви вводите їх правильно, коли ви робите це для себе.

Далі ми збираємося надрукувати символи «Загальний час:», за якими слідує значення загального часу, що минув для цього запуску програми (представлений %E).

Ми використовуємо n, щоб дати ще один новий рядок. Потім ми надрукуємо символи «Режим користувача (s)», а потім значення часу ЦП, проведеного в режимі користувача, позначене %U.

Ми використовуємо n, щоб дати ще один новий рядок. Цього разу ми готуємося до значення часу ядра. Ми друкуємо символи «Режим ядра (s)», а потім специфікатор формату часу ЦП, проведеного в режимі ядра, тобто %S.

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

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

time -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./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 відображається у вікні терміналу, а результати від часу надходять у файл 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

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

І ми поза часом

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