При разработке локальных утилит и специализированных обработок в 1С часто возникает вопрос: какой интерфейс выбрать для максимального быстродействия — обычные или управляемые формы? Ситуация становится особенно критичной, когда приложение активно взаимодействует с внешними библиотеками через COMОбъект, перехватывает сотни или тысячи событий построчной передачи данных и выполняет поиск и расчеты в таблицах значений.
Разберем детально, как архитектурные особенности обоих подходов влияют на производительность и какие факторы необходимо учитывать при выборе платформенного решения.
Главное различие кроется в модели исполнения программного кода:
&НаСервере, &НаСервереБезКонтекста) сопровождается сериализацией параметров, передачей контекста формы и блокировкой интерфейсного потока.Рассмотрим, как платформа 1С взаимодействует с внешними компонентами. Метод ДобавитьОбработчик для перехвата динамических событий внешнего объекта может быть назначен только на клиенте:
// Создание объекта и подключение обработчика события на клиенте
ВнешнийОбъект = Новый COMОбъект("ExternalComponent.Application");
ДобавитьОбработчик ВнешнийОбъект.ПолучениеДанных, ОбработкаПолученияДанных;
Когда COM-объект возвращает данные построчно (например, генерирует событие 1000 раз подряд), обработчик ОбработкаПолученияДанных вызывается в контексте клиента 1000 раз. В управляемом приложении здесь возникает узкое место:
ТаблицаЗначений недоступен на тонком клиенте. На клиенте разработчику доступен только объект ДанныеФормыКоллекция (строки таблицы формы) или массивы и структуры. Построчная модификация элементов формы в реальном времени вызывает постоянную перерисовку интерфейса и тормозит обработку потока COM-событий.В обычных формах этой проблемы нет: в обработчике события мы напрямую обращаемся к локальному объекту ТаблицаЗначений, не тратя процессорное время на передачу контекста и обновление интерфейсных связей.
Если для задачи все же выбраны управляемые формы или требуется максимальная скорость вычислений в локальной таблице, применим следующие оптимизационные приемы:
Массив. Передачу данных на форму или сервер выполняем один раз пакетно по завершении всего процесса выгрузки.НайтиСтроки() в объекте ТаблицаЗначений обязательно создаем индексы. Это переводит сложность поиска с линейного перебора O(N) в быстрый поиск по индексу:
// Добавление индекса для ускорения поиска
ТаблицаДанных.Индексы.Добавить("Идентификатор");
Отбор = Новый Структура("Идентификатор", ИскомоеЗначение);
НайденныеСтроки = ТаблицаДанных.НайтиСтроки(Отбор);
Соответствие вместо обхода элементов коллекций.Запрос: если над несколькими таблицами значений требуется выполнять сложные сопоставления, объединения, группировки или агрегатные вычисления, передаем их в качестве параметров запроса на сервере (через МенеджерВременныхТаблиц). Код запроса исполняется платформой на уровне оптимизированного ядра С++, что в разы быстрее интерпретируемых циклов Для Каждого в коде 1С.Проанализировав условия задачи (один пользователь, файловая база, отсутствие прикладных объектов метаданных, построчные события COM и активные вычисления в памяти), делаем вывод: