В некоторых ситуациях нам нужно точно знать, сколько времени потребовалось для выполнения конкретной команды или сценария. Конечно, вы можете самостоятельно засечь время или использовать секундомер, чтобы узнать продолжительность обработки команды. К счастью, существует команда time, которая избавит вас от всех этих проблем.
Командная строка предлагает множество одноцелевых утилит, благодаря которым нет необходимости писать дополнительный код. Команда time – одна из таких команд. Важно помнить, что команда time никак не связана с командой date, которая выводит дату и время системы. Утилита time измеряет время выполнения программы или сценария и сообщает вам полученное значение.
В этом мануале вы узнаете, как использовать команду time и как читать ее выходные данные.
Примечание: Если не указано иное, примеры в этом руководстве выполняются в оболочке Bash в Linux.
1: Время выполнения команды
Чтобы рассчитать продолжительность выполнения команды, укажите в ней time в качестве префикса.
Время работы программы или зачем нужна асимптотика | Григорий Шовкопляс
Метод выполнения time зависит от вашей операционной системы. В некоторых оболочках (bash и zsh, например) утилита time является встроенной командой; но также есть и отдельная команда GNU time – и ее аргументы отличаются от тех, что использует встроенная time.
Используйте следующую команду, чтобы посмотреть, как работает time в вашей системе:
Вы получите такой результат:
time is a shell keyword
time is /usr/bin/time
В этом случае есть и встроенная команда оболочки time, и версия time , установленная в каталог /usr/bin/time.
Если вы хотите использовать GNU-версию time, вы можете поставить перед ней обратный слеш:
Если вы этого не сделаете, оболочка будет использовать встроенную версию.
Примечание: Оболочка fish не имеет собственной реализации time. Если вы используете fish, вам нужно убедиться, что у вас установлена GNU команда time.
Оба метода служат одной и той же цели, хотя версия GNU имеет более продвинутые параметры форматирования.
Давайте исследуем время выполнения команды tree в корне вашей файловой системы. Эта команда отобразит визуальное дерево всех ваших файлов и каталогов.
Команда tree не всегда установлена по умолчанию, но в системах Ubuntu и Debian вы можете установить ее с помощью apt:
sudo apt install tree
В macOS ее можно установить с помощью Homebrew:
brew install tree
Теперь, когда команда tree установлена, используйте ее, чтобы просмотреть все файлы в системе, и добавьте к ней префикс time, чтобы узнать, сколько времени это займет:
Вы увидите, как прокручивается информация о файлах. В конце концов команда покажет вам потраченное время:
# Здесь будет вывод команды tree.
166590 directories, 1568127 files
tree / 12.24s user 10.37s system 66% cpu 33.827 total
Обратите внимание, что выполненная вами команда tree / повторяется командой time. Вывод отображает несколько фрагментов информации, но пока мы сосредоточимся на значении total:
Урок 2 Варианты выполнения кода. Первая программа на Python
tree / 12.24s user 10.37s system 66% cpu 33.827 total
Именно столько времени потребовалось для выполнения команды в секундах.
Команда time также работает, если вы отменили выполнение команды с помощью Ctrl+C. Если вы снова запустите time tree / и быстро нажмете Ctrl+C, вывод команды tree остановится, а на экране будут представлены результаты time за то время, что успела поработать команда до того, как вы ее остановили.
2: Использование ресурсов
Вывод time включает три значения в дополнение к общей продолжительности выполнения команды, total.
tree / 12.24s user 10.37s system 66% cpu 33.827 total
Первое значение – user. Это общее количество времени (в CPU-секундах), которое команда провела в пользовательском режиме.
Следующее значение, system – это количество времени (тоже в CPU-секундах), которое команда провела в режиме системы или ядра.
Наконец, cpu – это процент использования ЦП, выделенного команде.
Разница между пользовательским и системным временем заключается в использовании ЦП, которое разбивается по уровням доступа. Когда код выполняется в пользовательском режиме, он не имеет прямого доступа к оборудованию или памяти и должен полагаться на API системы. Так работает большая часть кода в вашей системе, благодаря такой его изоляции всегда можно исправить сбои.
В свою очередь, в режиме ядра исполняемый код имеет неограниченный доступ к системному оборудованию. Этот режим в значительной степени зарезервирован для наиболее надежных функций операционной системы. Когда какой-либо код сталкивается с ошибкой в режиме ядра, из-за полного доступа эти ошибки приводят к сильным сбоям и, как правило, приводят к сбою системы в целом.
Заключение
В этом мануале вы узнали, как при помощи команды time узнать, сколько времени потребовалось для выполнения команд и сценариев и на что именно потрачено это время. Команда time, встроенная в вашу оболочку, дает вам быстрый доступ к расчету продолжительности выполнения запущенных команд без каких-либо дополнительных средств.
Источник: www.8host.com
Измерение производительности JavaScript-функций
Измерение времени, которое уходит на выполнение функции — это хороший способ доказательства того, что одна реализация некоего механизма является более производительной, чем другая. Это позволяет удостовериться в том, что производительность функции не пострадала после неких изменений, внесённых в код. Это, кроме того, помогает искать узкие места производительности приложений.
Если веб-проект обладает высокой производительностью — это вносит вклад в его позитивное восприятие пользователями. А если пользователям понравилось работать с ресурсом — они имеют свойство возвращаться. Например, в этом исследовании показано, что 88% онлайн-клиентов менее склонны возвращаться на ресурсы, при работе с которыми они столкнулись с какими-то неудобствами. Эти неудобства вполне могут быть вызваны проблемами с производительностью.
Именно поэтому в деле веб-разработки важны инструменты, помогающие находить узкие места производительности и измерять результаты улучшений, вносимых в код. Подобные инструменты особенно актуальны в JavaScript-разработке. Здесь важно знать о том, что каждая строка JavaScript-кода может, в потенциале, заблокировать DOM, так как JavaScript — это однопоточный язык.
В этом материале я расскажу о том, как измерять производительность функций, и о том, что делать с результатами измерений.
Если вы полагаете, что некоторые вычисления слишком тяжелы для выполнения их в главном потоке, то вы, возможно, решите переместить их в сервис-воркер или в веб-воркер.
Метод performance.now()
Интерфейс Performance даёт доступ к значению типа DOMHighResTimeStamp через метод performance.now() . Этот метод возвращает временную метку, указывающую на время в миллисекундах, прошедшее с момента начала существования документа. Причём, точность этого показателя составляет порядка 5 микросекунд (доли миллисекунды).
Для того чтобы измерить производительность фрагмента кода, пользуясь методом performance.now() , нужно выполнить два измерения времени, сохранить результаты этих измерений в переменных, а затем вычесть из результатов второго измерения результаты первого:
const t0 = performance.now(); for (let i = 0; i < array.length; i++) < // какой-то код >const t1 = performance.now(); console.log(t1 — t0, ‘milliseconds’);
В Chrome после выполнения этого кода можно получить примерно такой результат:
0.6350000001020817 «milliseconds»
В Firefox — такой:
1 milliseconds
Как видно, результаты измерений, полученные в разных браузерах, серьёзно различаются. Дело в том, что в Firefox 60 точность результатов, возвращаемых API Performance, снижена. Мы ещё поговорим об этом.
Интерфейс Performance обладает гораздо большими возможностями, чем только возврат некоей временной метки. К ним относятся измерение различных аспектов производительности, представленные такими расширениями этого интерфейса, как API Performance Timeline, Navigation Timing, User Timing, Resource Timing. Вот материал, в котором можно найти подробности об этих API.
В нашем случае речь идёт об измерении производительности функций, поэтому нам достаточно возможностей, которые даёт метод performance.now() .
Date.now() и performance.now()
Тут у вас может возникнуть мысль о том, что для измерения производительности можно пользоваться и методом Date.now() . Это и правда возможно, но у такого подхода есть недостатки.
Метод Date.now() возвращает время в миллисекундах, прошедшее с эпохи Unix (1970-01-01T00:00:00Z) и зависит от системных часов. Это означает не только то, что этот метод не так точен, как performance.now() , но и то, что он, в отличие от performance.now() , возвращает значения, которые в определённых условиях могут быть основаны на неправильных показателях часов.
Вот что об этом говорит Рич Джентлкор — программист, имеющий отношение к движку WebKit: «Возможно, программисты реже думают о том, что показания, возвращаемые при обращении к Date , основанные на системном времени, совершенно нельзя назвать идеальными для мониторинга реальных приложений. В большинстве систем работает демон, который регулярно синхронизирует время. Подстройка системных часов на несколько миллисекунд каждые 15-20 минут — это обычное дело. При такой частоте настройки часов около 1% измерений 10-секундных интервалов окажутся неточными».
Метод console.time()
Измерение времени с использованием этого API производится крайне просто. Достаточно, перед кодом, производительность которого нужно оценить, вызвать метод console.time() , а после этого кода — метод console.timeEnd() . При этом и тому и другому методам нужно передать один и тот же строковой аргумент. На одной странице одновременно можно использовать до 10000 подобных таймеров.
Точность измерений времени, производимых с помощью этого API, такая же, как и при использовании API Performance, но то, какой именно точности удастся достичь в каждой конкретной ситуации, зависит от браузера.
console.time(‘test’); for (let i = 0; i < array.length; i++) < // какой-то код >console.timeEnd(‘test’);
После выполнения подобного кода система автоматически выведет в консоль сведения о прошедшем времени.
В Chrome это будет выглядеть примерно так:
test: 0.766845703125ms
test: 2ms — timer ended
Собственно говоря, тут всё очень похоже на то, что мы видели, работая с performance.now() .
Сильная сторона метода console.time() заключается в простоте его использования. А именно, речь идёт о том, что его применение не требует объявления вспомогательных переменных и нахождения разницы между записанными в них показателями.
Сниженная точность временных показателей
Если вы, пользуясь вышеописанными средствами, измеряли производительность своего кода в разных браузерах, то вы могли обратить внимание на то, что результаты измерений могут различаться.
Причиной этого является то, что браузеры пытаются защитить пользователей от атак, основанных на анализе времени, и от механизмов идентификации браузеров (Browser Fingerprinting). Если результаты измерения времени окажутся слишком точными, это может дать злоумышленникам возможность, например, идентифицировать пользователей.
В Firefox 60, как уже было сказано, точность результатов измерения времени снижена. Это сделано с помощью установки значения свойства privacy.reduceTimerPrecision в значение 2 мс.
Кое-что, о чём стоит помнить, тестируя производительность
Теперь в вашем распоряжении есть инструменты, позволяющие измерять производительность JavaScript-функций. Но, прежде чем приняться за дело, нужно учитывать некоторые особенности, о которых мы сейчас поговорим.
▍Разделяй и властвуй
Предположим, что вы, фильтруя некие данные, обратили внимание на медленную работу приложения. Но вы не знаете о том, где именно находится узкое место производительности.
Вместо того чтобы строить догадки о том, какая именно часть кода работает медленно, лучше будет выяснить это, воспользовавшись вышеописанными методиками.
Для того чтобы увидеть общую картину происходящего, сначала стоит, воспользовавшись console.time() и console.timeEnd() , оценить производительность блока кода, который, предположительно, плохо влияет на производительность. Затем надо посмотреть на скорость работы отдельных частей этого блока. Если одна из них выглядит заметно медленнее, чем другие, нужно уделить ей особое внимание и как следует её проанализировать.
Чем меньше кода находится между вызовами методов, измеряющих время, тем ниже вероятность того, что измеряться будет что-то, не имеющее отношения к проблемной ситуации.
▍Учитывайте особенности поведения функций при разных входных значениях
В реальных приложениях данные, поступающие на вход конкретной функции, могут быть очень разными. Если измерить производительность функции, которой передали некий произвольно выбранный набор данных, это не даст никаких ценных сведений, способных прояснить происходящее.
Функции при исследовании производительности нужно вызывать с входными данными, максимально напоминающими реальные.
▍Запускайте функции по много раз
Предположим, у вас имеется функция, которая перебирает массив. Она выполняет некие вычисления, используя каждый элемент массива, а после этого возвращает новый массив с результатами вычислений. Вы, размышляя об оптимизации этой функции, хотите узнать о том, что в вашей ситуации работает быстрее — цикл forEach или обычный цикл for .
Вот два варианта подобной функции:
function testForEach(x) < console.time(‘test-forEach’); const res = []; x.forEach((value, index) =>< res.push(value / 1.2 * 0.1); >); console.timeEnd(‘test-forEach’) return res; > function testFor(x) < console.time(‘test-for’); const res = []; for (let i = 0; i < x.length; i ++) < res.push(x[i] / 1.2 * 0.1); >console.timeEnd(‘test-for’) return res; >
const x = new Array(100000).fill(Math.random()); testForEach(x); testFor(x);
После запуска кода мы получаем следующие результаты:
test-forEach: 27ms — timer ended test-for: 3ms — timer ended
Похоже, цикл forEach оказался гораздо медленнее цикла for . Ведь результаты тестирования указывают именно на это?
На самом деле, после однократного испытания рано делать подобные выводы. Попробуем вызвать функции по два раза:
testForEach(x); testForEach(x); testFor(x); testFor(x);
test-forEach: 13ms — timer ended test-forEach: 2ms — timer ended test-for: 1ms — timer ended test-for: 3ms — timer ended
Получается, что функция, в которой используется forEach , вызванная второй раз, оказывается такой же быстрой, как и та, в которой применяется for . Но, учитывая то, что при первом вызове forEach -функция работает заметно медленнее, её, возможно, всё же использовать не стоит.
▍Тестируйте производительность в разных браузерах
Вышеприведённые тесты выполнялись в Firefox. А что если выполнить их в Chrome? Результаты будут совсем другими:
test-forEach: 6.156005859375ms test-forEach: 8.01416015625ms test-for: 4.371337890625ms test-for: 4.31298828125ms
Дело в том, что браузеры Chrome и Firefox основаны на разных JavaScript-движках, в которых реализованы разные оптимизации производительности. Об этих различиях весьма полезно знать.
В данном случае в Firefox наблюдается лучшая оптимизация forEach при сходных входных данных. А цикл for оказывается быстрее чем forEach и в Chrome, и в Firefox. В результате, вероятно, лучше остановиться именно на варианте функции с for .
Это — хороший пример, демонстрирующий важность измерения производительности в разных браузерах. Если оценить производительность некоего кода только в Chrome, то можно прийти к выводу о том, что цикл forEach , в сравнении с циклом for , не так уж и плох.
▍Применяйте искусственные ограничения системных ресурсов
Значения, которые получены в наших экспериментах, не выглядят особенно большими. Но знайте о том, что компьютеры, которые используют для разработки, обычно гораздо быстрее чем, скажем, средний мобильный телефон, на котором просматривают веб-страницы.
Для того чтобы поставить себя на место пользователя, обладающего не самым быстрым устройством, воспользуйтесь возможностями браузера по искусственному ограничению системных ресурсов. Например — по снижению производительности процессора.
При таком подходе 10 или 50 миллисекунд легко могут превратиться в 500.
▍Измеряйте относительную производительность
Результаты измерений производительности обычно зависят не только от аппаратного обеспечения, но и от текущей нагрузки на процессор, и от загруженности главного потока JavaScript-приложения. Поэтому постарайтесь опираться на относительные показатели, характеризующие изменение производительности, так как абсолютные показатели, полученные при анализе одного и того же фрагмента кода в разное время, могут сильно различаться.
Итоги
В этом материале мы рассмотрели некоторые JavaScript-API, предназначенные для измерения производительности. Мы поговорили и о том, как использовать их для анализа реального кода. Я полагаю, что для того чтобы выполнить какие-то простые измерения, проще всего пользоваться console.time() .
У меня есть такое ощущение, что многие фронтенд-разработчики не уделяют достаточно внимания измерению производительности своих проектов. А им стоило бы постоянно следить за соответствующими показателями, так как производительность влияет на успешность и прибыльность проектов.
Уважаемые читатели! Если вы постоянно контролируете производительность своих проектов, просим рассказать о том, как вы это делаете.
- Блог компании RUVDS.com
- Разработка веб-сайтов
- JavaScript
Источник: habr.com
Определяем время работы скрипта PHP
Доброго времени суток, коллеги!
Сегодня я решил затронуть такую тему, как время выполнения скрипта PHP и его определение.
Не скажу, что данная необходимость возникает каждый день, но время от времени на практике возникают ситуации, когда нужно получить время работы скрипта PHP.
Особенно часто за таким занятием можно застукать разработчиков, занимающихся рефакторингом кода и оптимизацией существующих алгоритмов, когда время выполнения PHP скрипта является ключевым фактором при выборе конечного варианта.
Ну, и ещё иногда данные цифры требуют менеджеры и заказчики, желающие выяснить, сколько времени потребуется на то или иное действие в коде.
Поэтому я и решил написать данную коротенькую заметку, в которой решил изложить порядок действий в аналогичной ситуации.
Сперва мы рассмотрим сам алгоритм определения времени исполнения PHP скрипта, а затем я приведу код, с помощью которого он будет реализовываться.
Время выполнения PHP скрипта — алгоритм определения
Порядок наших действий будет предельно прост:
- определяем текущее серверное время в PHP коде перед выполнением действий, прописанных в скрипте;
- после того, как скрипт выполнится, снова узнаём серверное время;
- вычисляем средствами PHP разницу времени между завершением выполнения скрипта и его запуском.
Полученное в итоге значение как раз и будет временем выполнения PHP скрипта, которое можно будет принимать во внимание при дальнейшей оптимизации и прочих действиях.
Время работы PHP скрипта — реализация алгоритма
Для вывода текущего времени в PHP коде я решил воспользоваться стандартной PHP функцией microtime(), которая возвращает текущую метку времени в Unix формате с микросекундами.
Зачем такая точность?
Затем, чтобы уловить малейшие изменения времени выполнения скриптов, т.к. иногда доли секунды могут быть фатальны и привести к большим потерям при использовании медленного кода в больших масштабах.
Ну, и плюс, учёт микросекунд при вычислениях влияет на точность калькуляций в положительную сторону.
Для демонстрации своих теоретических повествований я написал простенький скриптик, который вычисляет время прогона пустого цикла с 30 000 000 итераций (решил взять побольше для наглядности):
echo ‘Скрипт был выполнен за ‘ . (microtime(true) — $start) . ‘ секунд’;
Как сказано в официальной документации PHP, по умолчанию microtime() возвращает строку в формате «msec sec», где sec — количество секунд с начала эпохи Unix (1 января 1970 0:00:00 GMT), а msec — это количество микросекунд, прошедших после sec.
Функция PHP microtime() имеет всего один параметр get_as_float, при указании которому значения true можно получить текущее время PHP в секундах, прошедших с начала эпохи Unix с точностью до микросекунд.
Поскольку мне нужно было именно текущее время, а не количество секунд с начала эпохи Unix, то я воспользовался данным параметром, что можно видеть в моём коде.
В итоге, с помощью функции echo(), на экран вывелось следующее сообщение: Скрипт был выполнен за 1.3156361579895 секунд.
Чтобы определить, что данная методика работает верно, я решил задать фиксированное время выполнения скрипта с помощью функции sleep(), которая делает задержку выполнения скрипта на указанное количество секунд.
В итоге, следующая конструкция вернула сообщение Скрипт был выполнен за 2.0000510215759 секунд:
Превышение указанной задержки на микроскопические доли секунд можно списать на время вызова кодовых конструкций и обработку результатов их выполнения серверным железом, поэтому на них вполне можно закрыть глаза.
Если они будут всё-таки раздражать вас или вашего заказчика, то можете воспользоваться хаком в виде банального округления до сотых или тысячных долей с помощью PHP функции round(), задействовав её следующим образом:
round(microtime(true) — $start, 2);
Результатом выполнения данного куска кода для вышеприведённого примера станет значение в кругленькие 2 секунды, что устроит самых искушённых перфекционистов
На этом сегодняшняя информация о том, как можно определить время выполнения скрипта PHP, подходит к концу.
Пишите свои отзывы в комментариях и задавайте интересующие вас вопросы в пабликах проекта в социальных сетях.
Всем удачи и до новых встреч!
Понравилась статья? Поделись с друзьями:
‘ . __( ‘Pages:’, ‘themonic’ ), ‘after’ => ‘
- 5
- 4
- 3
- 2
- 1
Источник: cccp-blog.com