Почему обращение к реквизиту через точку тормозит систему и как это исправить

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

В процессе разработки на платформе 1С:Предприятие 8 каждый программист сталкивается с дилеммой: написать простой код вида Ссылка.Склад или использовать методы БСП для получения значений реквизитов. На первый взгляд кажется, что разницы нет, но при работе с большими данными «простой» путь может привести к катастрофическому падению производительности и утечкам памяти. Рассмотрим подробнее, почему так происходит, и разберем механизмы работы платформы «под капотом».

Суть проблемы: эксперимент с «тяжелым» документом

Проанализируем ситуацию, описанную автором темы. Представим документ, в котором есть реквизит типа ХранилищеЗначения (например, с фотографией весом 5 МБ) и табличная часть на 200 строк. Если таких документов в базе много, объем данных одного объекта может достигать внушительных размеров. Если мы попытаемся прочитать обычную ссылку на склад через точку, то замер производительности контура 1С покажет значительные задержки.

Склад = СсылкаНаДокумент.Склад;

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

Механизм объектного кэширования: почему «точка» — это дорого

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

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

Таким образом, даже если вам нужна только Дата или Склад, 1С заставляет СУБД прочитать, а сервер приложений — обработать и сохранить в памяти все 5 МБ картинок и тысячи строк табличных частей этого документа. Чтобы вовремя обнаружить такие проблемные участки, разработчиками часто используется статический анализатор кода проектов.

Разберем альтернативу: функции БСП и запросы

Функции стандартных библиотек, подробнее о которых можно узнать, изучив справочник по методам БСП с примерами использования, работают принципиально иначе. Проанализируем их внутреннее устройство:

Именно поэтому такой подход работает в десятки и сотни раз быстрее на крупных объектах.

Когда использование точки оправдано?

Не стоит впадать в крайности и заменять абсолютно все обращения через точку на запросы. Рассмотрим ситуации, когда «точка» допустима:

  1. Маленькие справочники: Обращение к коду валюты (СсылкаВалюта.Код) или ставке НДС обычно не вызывает проблем, так как эти объекты малы и, скорее всего, уже находятся в кэше.
  2. Работа с объектом: Если вам в любом случае нужно модифицировать объект и вы вызываете ПолучитьОбъект(), то данные всё равно будут прочитаны целиком. В этом случае чтение реквизитов через точку от полученного объекта уже не несет дополнительных затрат.
  3. Повторное обращение: Если в рамках одного алгоритма вы обращаетесь к 10-15 разным реквизитам одного и того же объекта, кэширование может сработать в плюс, так как будет выполнен всего один запрос к базе вместо десяти.

Опасности обращения через точку на клиенте

Особое внимание уделим клиент-серверному взаимодействию. Вызов Ссылка.Реквизит на стороне клиента — это «смертный грех» разработчика 1С. Посмотрим на цепочку событий:

  1. Клиент обращается к серверу за данными.
  2. Сервер читает весь объект из СУБД (включая тяжелые ТЧ).
  3. Сервер сериализует весь этот объем и передает его по сети на клиент.
  4. Интерфейс пользователя «замирает» на время передачи мегабайтов данных.

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

Практические советы и «Золотое правило»

Для оптимизации кода придерживайтесь следующих рекомендаций:

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

2. Использование массового получения реквизитов: Если нужно несколько полей, используйте:


СтруктураДанных = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Ссылка, "Склад, Номер, Дата, Проведен");
// Теперь данные в структуре, и объект не грузится в кэш

3. Теория разбитых окон: Как справедливо замечено в обсуждении, если один «гуру» напишет Валюта.Код, то пришедший следом новичок по аналогии напишет ЗаказКлиента.Номер, что на больших базах приведет к деградации системы. Старайтесь придерживаться единого стандарта качественного кода.

Резюме

Выяснив причину медленной работы «точки», мы понимаем: это не баг платформы, а особенность её архитектуры (Caching Strategy). Проектируйте свои системы так, чтобы минимизировать неявные загрузки тяжелых объектов. Используйте запросы для получения данных и поиск неоптимальных запросов SQL для контроля производительности, чтобы ваши отчеты и обработки летали даже на терабайтных базах данных.

← На главную