Как правильно использовать ТекущаяУниверсальнаяДатаВМиллисекундах и замерять время в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в процессе оптимизации или логирования работы конфигураций 1С разработчики сталкиваются с необходимостью точного замера времени выполнения определенных участков кода. На первый взгляд кажется логичным использовать для этого функцию ТекущаяУниверсальнаяДатаВМиллисекундах. Однако, если мы замеряем время вызова серверной процедуры с клиента, нас поджидает множество неочевидных проблем. Давайте подробно разберем, как работает отсчет времени в платформе, почему возникают ошибки в измерениях и как правильно профилировать код.

Откуда ведется отсчет времени в 1С?

Рассмотрим особенность функции ТекущаяУниверсальнаяДатаВМиллисекундах. Если вы попытаетесь вывести ее результат, то увидите огромное число (более 63 триллионов). Дело в том, что в отличие от многих других языков программирования, где отсчет "Unix-эпохи" начинается с 1 января 1970 года, платформа 1С считает миллисекунды, прошедшие с 1 января 0001 года (00:00:00 по UTC).

Так как функция возвращает универсальное время (по Гринвичу/UTC), для преобразования полученного значения обратно в локальное время пользователя нам нужно делать поправку на смещение часового пояса. В современных решениях для этих целей лучше использовать встроенный функционал Библиотеки стандартных подсистем (БСП) или метод УниверсальноеВремя.

Проблема клиентского и серверного времени

Проанализируем частую ошибку разработчиков при замерах производительности. Допустим, мы пытаемся вычислить точное время работы алгоритма на сервере, фиксируя время до вызова на клиенте, а затем вычитая время, зафиксированное внутри самой серверной процедуры.

Делать так категорически нельзя. Как справедливо отмечается в обсуждениях, клиент и сервер — это "разные вселенные". Системные часы на компьютере пользователя (клиента) и на сервере 1С не синхронизированы с абсолютной точностью. Между ними всегда есть рассинхронизация на миллисекунды, секунды, а в запущенных случаях системного администрирования — даже на минуты. Вычислить точную аппаратную или сетевую задержку таким образом не выйдет, так как в результат вмешается погрешность времени между двумя физическими машинами.

Сетевые задержки (Latency) и накладные расходы

Посмотрим на то, что мы на самом деле измеряем, если фиксируем время на клиенте до вызова серверной функции и после её возврата на клиент. В этом случае мы получаем общее время кругового обращения ("round-trip"). В эти миллисекунды входит сразу несколько этапов:

  1. Время передачи запроса по локальной сети или интернету от клиента к серверу.
  2. Время на сериализацию и десериализацию передаваемых параметров (превращение данных в формат для передачи и обратно).
  3. Затраты платформы 1С на создание серверного контекста (особенно если это контекстный вызов формы).
  4. Чистое время выполнения нашего алгоритма и запросов к базе данных на сервере.
  5. Время передачи готового результата обратно клиенту.

Поэтому огромная разница в миллисекундах не всегда означает, что тормозит именно код. Возможно, проблема в медленном сетевом канале между пользователем и сервером предприятия.

Альтернатива ручным замерам кода

Хотя вычисление разницы через ТекущаяУниверсальнаяДатаВМиллисекундах отлично подходит для фонового программного логирования длительности ключевых операций в журнал регистрации, для реального поиска узких мест этот метод избыточен и неточен.

Для оценки скорости кода мы всегда рекомендуем использовать встроенный в Конфигуратор или 1C:EDT механизм «Замер производительности».

Разберем по шагам его преимущества:

Важный нюанс: чтобы встроенный замер показал длительность выполнения серверных строк кода, служба сервера 1С:Предприятия обязательно должна быть запущена в режиме отладки (с параметром -debug). Иначе платформа покажет вам только клиентскую часть вызова, скрыв истинные причины "тормозов" алгоритма внутри серверных модулей.

← На главную