Наверное, каждый программист 1С (да и не только программист), открывая «Функции для технического специалиста» (ранее «Все функции») на массивных конфигурациях вроде ERP 2.4 и т.п., в своей жизни много раз задавался вопросом – почему же они так долго открываются??
Действительно, в зависимости от мощностей сервера «Все функции» могут открываться от 20 секунд до 2 минут!
«Ну, слишком много объектов в конфигурации, огромное количество констант, справочников, документов, регистров… – Отвечали себе страдающие пользователи. – Пока программа обойдёт в цикле все метаданные, пока построит дерево… Тут ничего не поделаешь…».
И все они были не правы! Я провёл собственное расследование, которое показало, что 97% времени построения дерева метаданных тратится на… Однако давайте сохраним интригу. Устраивайтесь поудобнее, нас ждёт интересное расследование, в результате которого, исправив один маленький косяк разработчиков платформы 1С, мы сократим открытие «Всех функций» с 2 минут до 3 секунд!
Поехали!
И первый вопрос, который нам предстоит решить, – как достать исходный код обработки «Функции для технического специалиста», ведь это системная обработка, которая зашита где-то внутри платформы.
К счастью, в этом нам помогла данная публикация: Недокументированное использование стандартных форм.
Воспользовавшись обработкой из данной статьи, я извлёк «Функции для технического специалиста» из платформы 8.3.18.1363 во внешнюю обработку.
Открываем извлечённую обработку в конфигураторе и восстанавливаем связь между реквизитами формы и элементами (в приведённой статье это описывается).
И смотрим код формы. Первое, что бросается в глаза, – весь код написан на английском языке, что довольно непривычно наблюдать 1С-никам. Но для нас это сейчас не играет роли.
Признаться честно, я не стал сразу искать в коде ошибку, вызывающую тормоза. Я был, как и многие, уверен, что ошибки там никакой нет, и дело просто в большом количестве метаданных (не могли же мудрые мужи совершить какой-то очевидный косяк в обработке, которой пользуются миллионы каждый день на протяжении последних лет 10, правда?), и возможно, нерациональной реализации обхода метаданных на уровне платформы.
Поэтому сразу бросился оптимизировать обработку другими способами. Ниже опишу свои потуги на данном поприще:
Проблема:
Запуская «Все функции», чаще всего нам надо открыть объект какой-то определённой ветки. Справочник/документ/регистр… При этом при открытии каждый раз подгружаются ВСЕ объекты метаданных, 90% которых нам изначально не нужно.
Решение:
При открытии обработки заполняем только верхний уровень метаданных. Открытие происходит мгновенно, затем пользователь разворачивает конкретную ветку метаданных, например «Справочники», и именно в этот момент программа подгружает все справочники в дерево. Да, программа подвисает в момент раскрытия ветки, но отрабатывает в 10 раз быстрее, потому что тратит время на подгрузку именно той ветки, которая нам нужна, а не всех.
Минусы решения:
Воспользоваться поиском можно только по подгруженным веткам метаданных. Если по привычке пользователь начнёт сразу вводить название объекта в поиск, не развернув ни одной ветки метаданных, он вообще ничего не найдёт.
Проблема:
Чаще всего мы используем «Все функции» для доступа к одним и тем же объектам, которые неудобно запускать из интерфейса подсистем (либо мы не знаем, где лежат эти объекты в подсистемах, либо объекты вообще не выведены в интерфейс). Суть в том, что, работая с программой, мы и сегодня, и завтра, и через неделю, скорее всего, будем запускать одни и те же объекты, которые вряд ли изменятся. Тогда зачем каждый раз при перезапуске 1С мы заново перечитываем все метаданные?
Решение:
Можно 1 раз считать метаданные, построить дерево и сохранить его в кэш, воспользовавшись хранилищем настроек пользователей. А при открытии «Всех функций» просто подгружать дерево метаданных из кэша. Скорость открытия обработки в таком случае сокращается до 2 секунд! При этом поиск по метаданным работает сразу, как мы привыкли.
Минусы решения:
При изменении метаданных, добавлении/удалении/переименовке объектов нам будут отображаться устаревшие данные из кэша. Частично можно обойти этот момент, добавив на форму кнопку «Перечитать». Либо делать перечитку метаданных и актуализацию кэша при запуске системы в фоновом задании. В принципе, с натяжкой можно считать это решение оптимальным, но оно требует много танцев с бубном и мало кто захочет так заморачиваться.
И тут мне в голову начинают закрадываться сомнения, что типовой код построения дерева метаданных так уж непогрешим. Виной всему популярная обработка «Администратор 1С (редактор объектов)».
Ведь при выборе там объекта для редактирования открывается по сути то же самое дерево метаданных, и открывается оно всего за пару секунд.
Как же так?
Давайте разбираться… С этого момента, собственно, начинается наше РАССЛЕДОВАНИЕ! Запустим «Замер производительности» на фрагменте кода, который заполняет ветку метаданных «Справочники», и посмотрим, куда система тратит наши ресурсы.
Результаты, думаю, поразят многих:
Действительно, почти 97% времени система тратит на ВСТАВКУ ИКОНКИ справочника в каждую строку дерева! Собственно, всё… РАССЛЕДОВАНИЕ ЗАВЕРШЕНО!
Стоп... Но почему так много?
А вот почему: каждый раз в цикле мы обращаемся к библиотеке картинок, а затем через точку уже к её элементу «Справочник». И так тысячи раз в цикле…
Но ведь… Можно один раз считать из библиотеки картинок иконку справочника в переменную, а в цикле просто вставлять значение из этой переменной?
Оптимизируем наш код:
Результаты шокируют: вместо 11 секунд ветка метаданных «Справочники» считывается меньше чем за секунду!
Проделаем эту операцию с каждым объектом метаданных. В самом начале процедуры считаем единожды нужные нам картинки из БиблиотекиКартинок и в цикле вставляем уже данные из этих переменных.
Результат: вместо 2 минут дерево метаданных строится 3 секунды!
Спасибо вам, уважаемые разработчики платформы. Суммарно сотни тысяч часов разработчиков и консультантов за все эти годы потрачены на неоптимальное доставание картинок из библиотеки в цикле…
P.S. Уважаемое сообщество, большая просьба, у кого есть возможность – донесите этот откровенный баг до разработчиков платформы, чтобы в новом релизе это пофиксили. Мы уже достаточно натерпелись!
P.P.S. А теперь небольшие мысли по поводу того, как жить дальше. В голову приходят 3 варианта:
1) Открывать «Все функции» каждый раз из внешней обработки.
2) Добавить расширение конфигурации, в него поместить подсистему «Все функции» и исправленную обработку.
Ну, либо в «НСИ и администрирование» добавить одним из пунктов. Суть в том, чтобы максимально быстро обеспечить открытие из интерфейса. Также можно назначить, например, чтобы подсистема отображалась только под полными правами.
3) Как мы знаем из обработки «Преобразование стандартных форм» (та самая статья, которая упоминалась в начале), обработка «ВсеФункции» хранится в этом ресурсном файле:
Если каким-то образом исправить код обработки в этом файле, а затем подменить файл в папке с установленной программой на клиентской машине, то типовая платформенная кнопка «Функции для технического специалиста» будет открывать нашу исправленную обработку вместо типовой. Пока не разбирался с реализацией данного варианта. Возможно, вскоре статья будет дополнена.
В приложении к данному материалу прикрепляю исправленную обработку «Функции для технического специалиста» из платформы 8.3.18.1363.
Спасибо за внимание! Берегите своё время! J
-------------------------------------------------
UPD: Дорогие коллеги, спасибо большое всем вам за то, что так тепло встретили данную публикацию. Честно говоря, даже в самых смелых мечтах не думал, что она вызовет здесь такой резонанс. Мне очень приятно! Также это внушает некую надежду на то, что в будущих релизах платформы данный косяк будет оперативно исправлен.
Так же отдельно хочу поблагодарить Максима Колкина (the1) за замечательную идею - через общую команду назначить горячую клавишу на открытие обработки. Пожалуй, сейчас это самый быстрый и простой способ вызова исправленных "Всех функций", даже быстрее, чем через стандартный пункт меню.
Поэтому я разработал расширение, в котором находится наша исправленная обработка "Все функции" и общая команда, которая открывает её при нажатии на горячие клавиши Ctrl + Shift + Q (клавиши можно заменить на любые другие).
Так же, как справедливо заметили в комментариях, данная обработка зависит от релиза платформы, поэтому, например, выдранная из версии 8.3.18, она не запустится на 8.3.14, а на 8.3.20 не будет отображать новых системных команд.
Я это исправил. Вытащил обработку из последнего на сегодняшний день релиза - 8.3.20.1710 и добился её корректного открытия на платформах, начиная с 8.3.14. Возможно в более ранних версиях она тоже будет работать, дайте знать в комментариях)
На сегодняшний день решение с расширением протестировано на следующих релизах:
- 8.3.14.1976
- 8.3.15.1747
- 8.3.16.1063
- 8.3.18.1363
- 8.3.20.1710
Надеюсь, это кому-то будет полезным) Всем ещё раз спасибо и удачи!)