Как оптимизировать производительность и правильно использовать паузы в 1С:Предприятие

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

В работе разработчика 1С вопросы производительности всегда стоят на первом месте. Однако понятие «скорость» в программировании многогранно: иногда нам нужно ускорить выполнение тяжелого алгоритма, а иногда — намеренно замедлить процесс, например, для ожидания ответа от внешнего сервиса или разделения нагрузки на сервер. В этой статье мы подробно разберем основные методики управления временем выполнения кода, проанализируем классические ошибки и рассмотрим современные подходы к архитектуре высокопроизводительных систем.

Запросы в циклах: когда это допустимо и в чем главная опасность

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

Основная проблема заключается не в самом тексте запроса, а в так называемом Network Roundtrip — сетевых задержках. Каждый вызов запроса инициирует обращение от сервера приложений 1С к серверу СУБД (например, MS SQL Server или PostgreSQL). Даже если сам запрос выполняется за 0,001 секунды, накладные расходы на установку соединения, передачу параметров и получение результата могут составлять десятки миллисекунд. При 1000 итераций цикла программа потратит десятки секунд только на «общение» между серверами.

Однако, как отмечают участники обсуждения, в некоторых случаях профессионалы сознательно идут на это, если объем выборки мал (например, 3-5 итераций) или если разработка сложного пакетного запроса займет несоизмеримо больше времени, чем принесет выгоды. Рассмотрим пример того, как делать не рекомендуется:


Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Цена ИЗ РегистрСведений.Цены.СрезПоследних(&Дата, Номенклатура = &Номенклатура)";
    Запрос.УстановитьПараметр("Дата", ТекущаяДата());
    Запрос.УстановитьПараметр("Номенклатура", СтрокаТЧ.Номенклатура);
    // Это замедляет работу из-за постоянных обращений к СУБД
    Результат = Запрос.Выполнить();
КонецЦикла;

Правильный подход: выгрузить все необходимые ключи (в данном случае — номенклатуру) в массив или таблицу значений, передать их в один запрос и получить результат целиком. Проанализируем ситуацию: один запрос с условием ГДЕ Номенклатура В (&МассивНоменклатуры) отработает в десятки раз быстрее, чем сотня мелких запросов.

Реализация программной паузы: как замедлить выполнение корректно

Иногда перед программистом стоит обратная задача — приостановить выполнение кода. Это часто требуется при интеграции с внешними системами (API маркетплейсов, банков), которые имеют лимиты на количество запросов в секунду. Если 1С будет отправлять данные слишком быстро, сервер на той стороне заблокирует IP-адрес компании.

Рассмотрим основные способы реализации паузы в 1С:

  1. Методы БСП (Библиотеки стандартных подсистем). Если ваша конфигурация основана на БСП, рекомендуется использовать штатную функцию ОбщегоНазначенияБТС.Пауза(). Она корректно работает на стороне сервера и часто используется для ожидания завершения фоновых заданий.
  2. Использование Windows Script Host (WSH). В старых версиях или специфических задачах часто применялся объект WScript.Shell. Рассмотрим пример кода:

Процедура ПриостановитьВыполнение(Секунд)
    ОбъектWSH = Новый COMОбъект("WScript.Shell");
    Команда = "ping -n 1 -w " + Формат(Секунд * 1000, "ЧГ=0") + " 127.255.255.255";
    ОбъектWSH.Run(Команда, 0, Истина);
КонецПроцедуры

Важный момент: использование метода Sleep через COM-объекты может полностью блокировать поток выполнения, что в клиентском приложении приведет к «зависанию» интерфейса. Для управляемых форм в современных версиях платформы (8.3.18+) лучше использовать асинхронный метод Ожидать().

Методики проведения документов: борьба за миллисекунды и стабильность

Выясним причину, по которой 1С изменила классическую методику контроля остатков. Это один из самых ярких примеров того, как изменение логики «ускорение через архитектуру» работает на практике.

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

Новая методика (контроль после записи): Рассмотрим этот алгоритм подробнее. 1С записывает движения документа сразу, даже если остаток уйдет в «минус». Затем одним запросом система проверяет: «А не стали ли итоги по этому товару отрицательными после моей записи?». Если стали — транзакция откатывается (Rollback). Этот метод значительно быстрее, так как:

Мифы об оптимизации: влияет ли стиль написания кода на скорость?

Разберем популярный спор о том, влияет ли написание условия Если ... Тогда в одну строку на производительность. С технической стороны, встроенный язык 1С компилируется в байт-код. Для компилятора наличие лишних переносов строк или пробелов не имеет значения — они игнорируются при генерации исполняемого кода.

Однако на что действительно стоит обратить внимание, так это на количество обращений «через точку». Проанализируем код:


// Плохой пример: каждое обращение через точку — скрытый запрос к базе
СкладНаименование = Объект.Склад.Наименование;
ОрганизацияНаименование = Объект.Организация.Наименование;

Каждое такое обращение (если объект не кэширован) заставляет платформу выполнять неявный запрос к таблице справочника. В цикле такие «точки» превращаются в сотни лишних запросов. Правильнее будет получить все нужные данные одним запросом или использовать ПолучитьОбъект() только в крайнем случае.

Заключение: баланс между скоростью и пониманием

Как справедливо заметили участники обсуждения, «перевод строки замедляет работу программиста, но облегчает понимание». Всегда нужно искать баланс. Если код выполняется 5 минут, но запускается раз в месяц — возможно, его оптимизация не окупит затрат на разработку. Но если речь идет о проведении чека на кассе или массовом формировании заказов, каждая миллисекунда становится критичной.

Основные выводы нашего анализа:

  1. Избегайте запросов в циклах везде, где это возможно, используя временные таблицы и массивы параметров.
  2. Для искусственного замедления используйте штатные средства БСП или платформенные асинхронные методы, чтобы не блокировать интерфейс пользователя.
  3. Используйте современную методику проведения документов (проверка после записи) для высоконагруженных систем.
  4. Помните, что чистота и читаемость кода («лесенка») важнее микро-оптимизаций синтаксиса, так как они не влияют на реальную скорость работы байт-кода.
← На главную