В процессе разработки на платформе 1С:Предприятие 8 каждый программист сталкивается с дилеммой: написать простой код вида Ссылка.Склад или использовать методы БСП для получения значений реквизитов. На первый взгляд кажется, что разницы нет, но при работе с большими данными «простой» путь может привести к катастрофическому падению производительности и утечкам памяти. Рассмотрим подробнее, почему так происходит, и разберем механизмы работы платформы «под капотом».
Проанализируем ситуацию, описанную автором темы. Представим документ, в котором есть реквизит типа ХранилищеЗначения (например, с фотографией весом 5 МБ) и табличная часть на 200 строк. Если таких документов в базе много, объем данных одного объекта может достигать внушительных размеров. Если мы попытаемся прочитать обычную ссылку на склад через точку, то замер производительности контура 1С покажет значительные задержки.
Склад = СсылкаНаДокумент.Склад;
Мы заметим, что система начинает потреблять огромное количество оперативной памяти, а выполнение кода затягивается. В то же время использование функции БСП или прямого запроса отрабатывает мгновенно. Выясним причину этого феномена.
Главная причина кроется в том, как платформа 1С работает с объектным кэшем. Когда вы обращаетесь к любому реквизиту через точку от ссылки (за исключением Представление в некоторых случаях), платформа выполняет следующие действия:
Таким образом, даже если вам нужна только Дата или Склад, 1С заставляет СУБД прочитать, а сервер приложений — обработать и сохранить в памяти все 5 МБ картинок и тысячи строк табличных частей этого документа. Чтобы вовремя обнаружить такие проблемные участки, разработчиками часто используется статический анализатор кода проектов.
Функции стандартных библиотек, подробнее о которых можно узнать, изучив справочник по методам БСП с примерами использования, работают принципиально иначе. Проанализируем их внутреннее устройство:
ВЫБРАТЬ ИмяРеквизита ИЗ ... ГДЕ Ссылка = &Ссылка.Именно поэтому такой подход работает в десятки и сотни раз быстрее на крупных объектах.
Не стоит впадать в крайности и заменять абсолютно все обращения через точку на запросы. Рассмотрим ситуации, когда «точка» допустима:
СсылкаВалюта.Код) или ставке НДС обычно не вызывает проблем, так как эти объекты малы и, скорее всего, уже находятся в кэше.ПолучитьОбъект(), то данные всё равно будут прочитаны целиком. В этом случае чтение реквизитов через точку от полученного объекта уже не несет дополнительных затрат.Особое внимание уделим клиент-серверному взаимодействию. Вызов Ссылка.Реквизит на стороне клиента — это «смертный грех» разработчика 1С. Посмотрим на цепочку событий:
Для предотвращения таких ситуаций рекомендуется проводить регулярный анализ конфигураций и расширений на наличие ошибок. Всегда используйте серверные функции или специализированные методы БСП для получения данных на клиенте.
Для оптимизации кода придерживайтесь следующих рекомендаций:
1. Правило одной точки в циклах: Никогда не обращайтесь к реквизитам через точку внутри цикла. Если вам нужно получить данные для списка ссылок, сначала соберите их в массив, а затем одним запросом получите все нужные поля. В этом вам поможет проверка запросов на лишнюю выборку, которая выявит избыточные поля.
2. Использование массового получения реквизитов: Если нужно несколько полей, используйте:
СтруктураДанных = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Ссылка, "Склад, Номер, Дата, Проведен");
// Теперь данные в структуре, и объект не грузится в кэш
3. Теория разбитых окон: Как справедливо замечено в обсуждении, если один «гуру» напишет Валюта.Код, то пришедший следом новичок по аналогии напишет ЗаказКлиента.Номер, что на больших базах приведет к деградации системы. Старайтесь придерживаться единого стандарта качественного кода.
Выяснив причину медленной работы «точки», мы понимаем: это не баг платформы, а особенность её архитектуры (Caching Strategy). Проектируйте свои системы так, чтобы минимизировать неявные загрузки тяжелых объектов. Используйте запросы для получения данных и поиск неоптимальных запросов SQL для контроля производительности, чтобы ваши отчеты и обработки летали даже на терабайтных базах данных.