Как замерить производительность кода 1С и узнать время выполнения каждого этапа в процентах?

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

При разработке и оптимизации процедур в 1С часто возникает необходимость понять, какая именно часть кода занимает больше всего времени. Представим ситуацию: у нас есть процедура, например, ПоискШтрихкода, которая последовательно выполняет несколько этапов: Этап1, Этап2 и Этап3. Наша задача — выяснить, сколько времени (в миллисекундах и в процентах от общего времени) тратится на каждый из этих этапов.

В этой статье мы подробно разберем два основных подхода к решению этой задачи: ручной программный замер (удобен для логирования конкретных операций) и использование штатного инструмента «Замер производительности» в конфигураторе (наиболее эффективен при анализе большого количества процедур).

Способ 1: Программный замер времени выполнения

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

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

Разберем пример кода, который реализует эту логику:


// Фиксируем начало выполнения первого этапа
Начало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. Вы получаете данные в переменных и можете сохранить их в базу данных или отправить администратору.
  2. Метод работает в пользовательском режиме без включения отладки.

Недостатки:

  1. Приходится менять код программы, добавляя множество переменных.
  2. Если процедур под сотню, "обернуть" каждый вызов в замер времени будет очень трудоемко и код станет нечитаемым.

Способ 2: Штатный инструмент «Замер производительности»

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

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

1. Подготовка к замеру

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

2. Процесс замера

  1. Откройте конфигуратор и запустите сеанс отладки («Отладка» — «Начать отладку»).
  2. В запущенном режиме 1С:Предприятие подготовьтесь к выполнению действия (откройте нужную форму), но не нажимайте кнопку выполнения сразу.
  3. Перейдите в конфигуратор и выберите в меню «Отладка» — «Замер производительности» (или нажмите соответствующую кнопку на панели инструментов).
  4. Вернитесь в пользовательский режим и нажмите кнопку, запускающую ваши процедуры (Этап1, Этап2 и т.д.).
  5. После завершения операции вернитесь в конфигуратор и отключите замер (снова нажмите кнопку замера).

3. Анализ результатов и проценты

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

Колонка «Время (%)»
Это именно то, что нам нужно. В этой колонке отображается доля времени, затраченная на выполнение конкретной строки кода относительно общего времени замера. Однако здесь есть важный нюанс: по умолчанию строки могут быть развернуты, и процент будет размазан по деталям.

Как увидеть проценты по процедурам (Этапам)?
В окне замера производительности код представлен иерархически. Если вы видите строку вызова процедуры, например Этап1();, обратите внимание на следующие показатели:

Чтобы не потеряться в тысячах строк кода, мы рекомендуем использовать группировки или сортировку:

  1. Кликните по заголовку колонки «Время» (или «Время %»), чтобы отсортировать строки. Самые «тяжелые» участки кода окажутся наверху. Именно на них (топ-5 или топ-10 строк) стоит обратить внимание в первую очередь. Как правило, устранение одной самой медленной проблемы дает больший прирост, чем оптимизация ста мелких процедур.
  2. Используйте свертку дерева вызовов (кнопки «плюс» и «минус» слева от кода), чтобы свернуть внутренности процедур Этап1, Этап2. Тогда в строке с вызовом процедуры вы увидите суммарный процент времени, который она заняла.

Рекомендации по оптимизации

Проанализировав результаты замера, мы часто обнаруживаем, что, например, Этап1 занимает 78% времени, а остальные — несущественные доли. В этом случае:

  1. Раскройте ветку кода самой медленной процедуры (в нашем примере — Этап1).
  2. Найдите внутри неё строки с максимальным процентом времени. Чаще всего это будут запросы (строка Запрос.Выполнить()) или циклы.
  3. Если проблема в запросе — проверьте индексы и оптимальность текста запроса.
  4. Если проблема в большом количестве вызовов (колонка «Кол.» показывает тысячи или миллионы), проверьте, нет ли «запросов в цикле» — это классическая ошибка, убивающая производительность.

Использование БСП: Подсистема «Оценка производительности»

Если вам требуется регулярно отслеживать производительность на рабочей базе без запуска отладчика, мы рекомендуем обратить внимание на Библиотеку Стандартных Подсистем (БСП), подсистему «Оценка производительности».

Она работает по методике APDEX. В код внедряются специальные метки:


// В начале этапа
ОценкаПроизводительности.НачатьЗамерВремени("КлючеваяОперация.Этап1");

// ... код этапа ...

// В конце этапа
ОценкаПроизводительности.ЗакончитьЗамерВремени("КлючеваяОперация.Этап1");

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

Вывод

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

Для программной логики внутри алгоритмов или вывода прогресса пользователю используйте разницу значений ТекущаяУниверсальнаяДатаВМиллисекундах(). А для мониторинга рабочей системы — механизмы БСП.

← На главную