W3docs

hrtime()

В этой статье рассматривается функция PHP hrtime(): обзор, принцип работы и примеры использования.

В этой статье рассматривается функция PHP hrtime(): что она делает, чем отличаются два режима возврата значений, почему монотонные часы делают её идеальным инструментом для бенчмаркинга, а также приведены рабочие примеры.

Введение в функцию hrtime()

hrtime() — это встроенная функция, доступная в PHP 7.3 и выше. Она считывает высокоточный системный таймер и возвращает текущее время с точностью до наносекунды. Основное назначение функции — бенчмаркинг: измерение времени выполнения фрагментов кода.

Ключевое понятие здесь — монотонность. Монотонные часы движутся только вперёд с постоянной скоростью; они не подвержены влиянию изменений системных часов, корректировок NTP или переходов на летнее/зимнее время. Именно это и нужно для измерения прошедшего времени. Функции системного времени, такие как microtime() и time(), могут перескочить назад или вперёд при коррекции системных часов во время измерения, что испортит результат бенчмарка.

Обратите внимание: hrtime() измеряет время, прошедшее с произвольной эпохи (часто с момента загрузки системы). Абсолютное значение само по себе не имеет смысла — оно полезно только как разница между двумя показаниями.

Синтаксис и возвращаемые значения

hrtime(bool $as_number = false): array|int|false
  • $as_number — если false (по умолчанию), возвращает двухэлементный массив [секунды, наносекунды]. Если true, возвращает одно целое число: общее время в наносекундах.
  • Возвращает false, если высокоточный таймер недоступен.

Форма с единственным целым числом (hrtime(true)) наиболее удобна для бенчмаркинга, поскольку позволяет напрямую вычитать два показания.

Бенчмаркинг с hrtime(true)

php— editable, runs on the server

Логика следующая: зафиксировать $start, выполнить код, зафиксировать $end, затем вычислить разность. Поскольку показания даются в наносекундах, разделите на 1e6 (1 000 000), чтобы получить миллисекунды, или на 1e9 — для получения секунд. Для паузы в 1,5 мс результат будет приблизительно 1.5 мс (точное значение немного варьируется из-за накладных расходов системы).

Считывание массива [секунды, наносекунды]

При вызове без аргумента hrtime() возвращает массив, который можно деструктурировать:

<?php
[$seconds, $nanoseconds] = hrtime();

echo "Seconds since epoch:     $seconds\n";
echo "Nanoseconds component:   $nanoseconds\n";

// Combine both parts into total nanoseconds yourself
$totalNs = $seconds * 1e9 + $nanoseconds;
echo "Total nanoseconds:       $totalNs\n";
?>

На практике эта форма редко нужна — hrtime(true) уже возвращает объединённое значение, — но она наглядно показывает, что именно сообщает таймер.

Когда использовать hrtime() вместо microtime()

  • Используйте hrtime() для микробенчмаркинга и любых измерений, где важна точность. Функция монотонна и обеспечивает точность до наносекунды.
  • Используйте microtime(), когда нужна временная метка системного времени (секунды с начала эпохи Unix), а не прошедший интервал.

Подводные камни

  • Точность вычислений с плавающей точкой. Деление наносекунд на 1e6 даёт число с плавающей точкой, что подходит для отображения, но может терять точность на очень длинных интервалах. Держите разность в целых наносекундах в процессе измерения и выполняйте преобразование только в конце.
  • Очень долгоработающие скрипты. На 32-битных сборках целочисленное значение наносекунд может переполниться. Для произвольно больших разностей используйте расширения bcmath или gmp для точной арифметики.
  • Не воспринимайте значение как дату. Это не Unix-временная метка; форматировать его с помощью date() нельзя.

Заключение

hrtime() — правильный инструмент для измерения времени выполнения PHP-кода. Используйте hrtime(true), чтобы зафиксировать показание в наносекундах до и после выполнения кода, вычтите одно из другого и переведите в нужные единицы. Монотонные часы делают результат надёжным даже при изменении системного времени — чего нельзя гарантировать при использовании microtime().

Практика

Практика
Какова цель функции hrtime() в PHP?
Какова цель функции hrtime() в PHP?
Was this page helpful?