Механизм оценки производительности, входящий в состав Библиотеки стандартных подсистем (БСП), является мощным инструментом для мониторинга реальной скорости работы системы «глазами пользователя» — для этого подойдёт система мониторинга и анализа производительности 1С. Однако при его внедрении разработчики часто сталкиваются с вопросами методологии: как замерять цепочки вызовов, уходящие в фоновые задания, и как система понимает, когда замер пора остановить. В этой статье мы подробно разберем внутреннее устройство этого механизма и лучшие практики его использования.
Рассмотрим ситуацию: вы вызываете метод НачатьЗамерВремени на клиенте с параметром Автозавершение = Истина. Многих смущает отсутствие явного вызова функции завершения. Разберем по шагам, как это работает «под капотом» БСП.
Система определяет окончание замера на клиенте через обработчик ожидания. Когда вы инициируете замер с флагом автозавершения, БСП регистрирует однократный обработчик ожидания с минимальным интервалом (обычно 0.1 секунды). Этот обработчик не сработает до тех пор, пока выполняется основной код вашей процедуры. Только когда управление вернется в «цикл событий» платформы (то есть когда интерфейс станет доступен пользователю), сработает этот обработчик и зафиксирует время финиша.
Это позволяет автоматически замерить не просто выполнение одной функции, а все время, пока интерфейс был заблокирован, включая вложенные серверные вызовы. Проанализируем пример использования на клиенте:
&НаКлиенте
Процедура КомандаВыполнитьДействие(Команда)
// Начинаем замер с автозавершением
ОценкаПроизводительностиКлиентСервер.НачатьЗамерВремени("МояДлительнаяОперация", Истина);
// Выполняем полезную работу (серверные вызовы и т.д.)
ВыполнитьДействиеНаСервере();
// Явно завершать замер не нужно — система сделает это сама
// как только управление выйдет из этой процедуры и обработчиков платформы.
КонецПроцедуры
Один из самых сложных сценариев — когда процесс начинается пользователем, а затем переходит в фоновое выполнение. В этом случае замер на клиенте зафиксирует только время «запуска», но не фактическую работу алгоритма. Выясним, как правильно организовать сквозной замер.
Методологически правильно разделять замер на две части:
Чтобы замерить работу внутри фонового задания, необходимо передать в него контекст замера. Рассмотрим, как это реализовать:
// В серверном коде, подготавливающем запуск фонового задания
Процедура ЗапуститьФоновыйПроцесс()
// Фиксируем время начала
ВремяНачала = ОценкаПроизводительности.НачатьЗамерВремени();
ИмяОперации = "ДлительныйРасчетДанных";
// Передаем эти параметры в фоновое задание
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ВремяНачалаЗамера", ВремяНачала);
ПараметрыЗадания.Вставить("ИмяОперации", ИмяОперации);
ФоновыеЗадания.Выполнить("МойМодуль.ВыполнитьРасчет", ПараметрыЗадания);
КонецПроцедуры
// Внутри фонового задания
Процедура ВыполнитьРасчет(ПараметрыЗадания) Экспорт
// Выполняем тяжелые вычисления...
// Завершаем замер, используя переданное время начала
ОценкаПроизводительности.ЗакончитьЗамерВремени(
ПараметрыЗадания.ИмяОперации,
ПараметрыЗадания.ВремяНачалаЗамера
);
КонецПроцедуры
Важный нюанс: замер в фоновом задании всегда должен завершаться явно вызовом ЗакончитьЗамерВремени, так как механизмы клиентского «автозавершения» там недоступны.
Частая ошибка — ставить замер внутри модуля объекта в процедуре ОбработкаПроведения. Проанализируем ситуацию: замер, завершенный в конце этой процедуры, не будет учитывать время фиксации транзакции (Commit). В высоконагруженных системах время ожидания блокировок при записи в БД может быть сопоставимо с временем самого проведения.
Рассмотрим правильный подход:
ПередЗаписью (на клиенте).ПослеЗаписи (на клиенте) с флагом автозавершения.Это позволит получить максимально честную цифру, которую видит пользователь: от нажатия «Провести и закрыть» до момента, когда форма действительно закрылась.
Если вы внедрили код замера, но не видите данных в регистре сведений ЗамерыПроизводительности, не спешите паниковать. Механизм БСП использует многоуровневое кэширование для минимизации влияния на производительность:
1. Локальный кэш: замеры накапливаются в оперативной памяти сеанса. Это предотвращает постоянные записи в базу данных при каждом чихе пользователя.
2. Регистр сведений: с определенной периодичностью (или при заполнении буфера) данные сбрасываются в регистр ЗамерыПроизводительности (см. анализ структуры индексов и производительности базы).
3. Агрегация: для отчетов данные используются из агрегированных таблиц, которые заполняются регламентным заданием ЭкспортЗамеровПроизводительности.
Совет по отладке: Чтобы убедиться, что замеры вообще работают (поможет инструмент пошаговой отладки без конфигуратора), проверьте значение константы ОценкаПроизводительностиВыполняется. Если она выключена, вызовы функций БСП будут просто игнорироваться, не возвращая ошибок.
Для эффективной работы нам понадобятся следующие функции общего модуля ОценкаПроизводительностиКлиентСервер (или ОценкаПроизводительности на сервере):
НачатьЗамерВремени(ИмяОперации, Автозавершение) — возвращает ДатаНачала (тип Число — текущее время в миллисекундах или секундах в зависимости от версии платформы).ЗакончитьЗамерВремени(ИмяОперации, ДатаНачала) — фиксирует результат в системе.При использовании строковых имен операций убедитесь, что они зарегистрированы в справочнике Ключевые операции. В новых версиях БСП предпочтительно использовать именно строковые идентификаторы, так как это упрощает перенос настроек между базами и работу в распределенных информационных системах. Для быстрой настройки параметров профиля производительности пригодится обработка для добавления ключевых операций в профиль APDEX.