При разработке и оптимизации процедур в 1С часто возникает необходимость понять, какая именно часть кода занимает больше всего времени. Представим ситуацию: у нас есть процедура, например, ПоискШтрихкода, которая последовательно выполняет несколько этапов: Этап1, Этап2 и Этап3. Наша задача — выяснить, сколько времени (в миллисекундах и в процентах от общего времени) тратится на каждый из этих этапов.
В этой статье мы подробно разберем два основных подхода к решению этой задачи: ручной программный замер (удобен для логирования конкретных операций) и использование штатного инструмента «Замер производительности» в конфигураторе (наиболее эффективен при анализе большого количества процедур).
Если нам необходимо получить точные цифры непосредственно во время выполнения кода (например, для записи в журнал регистрации или вывода пользователю), мы можем использовать функции работы с текущей датой и временем. Самый точный инструмент для этого — функция ТекущаяУниверсальнаяДатаВМиллисекундах(). Она позволяет зафиксировать время с точностью до миллисекунды.
Давайте рассмотрим алгоритм, который позволит нам рассчитать длительность каждого этапа и его долю в общем времени выполнения. Логика следующая: мы фиксируем время начала, выполняем код этапа, фиксируем время окончания, а затем вычисляем разницу.
Разберем пример кода, который реализует эту логику:
// Фиксируем начало выполнения первого этапа
Начало1 = ТекущаяУниверсальнаяДатаВМиллисекундах();
Этап1(); // Выполняем процедуру первого этапа
Конец1 = ТекущаяУниверсальнаяДатаВМиллисекундах();
// Вычисляем длительность первого этапа
Длит1 = Конец1 - Начало1; // результат в миллисекундах
// Фиксируем начало выполнения второго этапа
Начало2 = ТекущаяУниверсальнаяДатаВМиллисекундах();
Этап2(); // Выполняем процедуру второго этапа
Конец2 = ТекущаяУниверсальнаяДатаВМиллисекундах();
// Вычисляем длительность второго этапа
Длит2 = Конец2 - Начало2;
// Общее время выполнения (от начала первого до конца последнего)
// Либо можно сложить длительности: ДлитОбщая = Длит1 + Длит2
Конец = ТекущаяУниверсальнаяДатаВМиллисекундах();
ДлитОбщая = Конец - Начало1;
// Теперь рассчитаем доли в процентах
// Используем функцию Окр для получения целого числа процентов
Если ДлитОбщая > 0 Тогда
Доля1 = Окр(Длит1 / ДлитОбщая * 100); // Процент времени на Этап 1
Доля2 = Окр(Длит2 / ДлитОбщая * 100); // Процент времени на Этап 2
Иначе
Доля1 = 0;
Доля2 = 0;
КонецЕсли;
// Выводим результат (пример)
Сообщить("Этап 1: " + Доля1 + "% (" + Длит1 + " мс)");
Сообщить("Этап 2: " + Доля2 + "% (" + Длит2 + " мс)");
Преимущества этого метода:
Недостатки:
Когда процедур много (как в случае, если у вас "под сотню" методов), ручной замер становится неэффективным. Здесь нам на помощь приходит встроенный в конфигуратор инструмент — Замер производительности. Он позволяет без изменения кода увидеть детальную картину выполнения.
Давайте разберем по шагам, как им пользоваться и как увидеть заветные проценты.
Для корректного замера необходимо убедиться, что сервер 1С:Предприятия запущен с ключом отладки (-debug), если выполняемый код находится на сервере. В файловой версии это происходит автоматически.
Этап1, Этап2 и т.д.).После остановки замера перед вами откроется таблица с результатами. Именно здесь мы найдем ответы на наши вопросы. Давайте проанализируем колонки, которые нам предоставляет платформа:
Колонка «Время (%)»
Это именно то, что нам нужно. В этой колонке отображается доля времени, затраченная на выполнение конкретной строки кода относительно общего времени замера. Однако здесь есть важный нюанс: по умолчанию строки могут быть развернуты, и процент будет размазан по деталям.
Как увидеть проценты по процедурам (Этапам)?
В окне замера производительности код представлен иерархически. Если вы видите строку вызова процедуры, например Этап1();, обратите внимание на следующие показатели:
Чтобы не потеряться в тысячах строк кода, мы рекомендуем использовать группировки или сортировку:
Этап1, Этап2. Тогда в строке с вызовом процедуры вы увидите суммарный процент времени, который она заняла.Проанализировав результаты замера, мы часто обнаруживаем, что, например, Этап1 занимает 78% времени, а остальные — несущественные доли. В этом случае:
Этап1).Запрос.Выполнить()) или циклы.Если вам требуется регулярно отслеживать производительность на рабочей базе без запуска отладчика, мы рекомендуем обратить внимание на Библиотеку Стандартных Подсистем (БСП), подсистему «Оценка производительности».
Она работает по методике APDEX. В код внедряются специальные метки:
// В начале этапа
ОценкаПроизводительности.НачатьЗамерВремени("КлючеваяОперация.Этап1");
// ... код этапа ...
// В конце этапа
ОценкаПроизводительности.ЗакончитьЗамерВремени("КлючеваяОперация.Этап1");
Система автоматически сохраняет результаты в регистр сведений. Позже администратор может сформировать отчет и увидеть среднее время выполнения, количество операций и динамику ухудшения или улучшения производительности по дням.
Для разового анализа и поиска узких мест лучше всего подходит штатный замер производительности в конфигураторе. Он сразу показывает проценты, полное время и количество вызовов, позволяя быстро локализовать проблему.
Для программной логики внутри алгоритмов или вывода прогресса пользователю используйте разницу значений ТекущаяУниверсальнаяДатаВМиллисекундах(). А для мониторинга рабочей системы — механизмы БСП.