Стоит ли использовать РеквизитФормыВЗначение

02.07.15

База данных - HighLoad оптимизация

В статье рассматривается вопрос производительности при использовании функции РеквизитФормыВЗначение.

Сам вопрос возник из размышлений: "Что лучше: использовать общий код в модуле объекта для управляемых и неуправляемых формах или все-таки дублировать код для разных форм?" Путем гугления наткнулся на вот эту статью по сабжу, но к сожалению, в в ней вопрос прозводительности не затрагивался.

Итак, я подготовил код и приступил к замерам производительности. Т.к. меня интересует только дополнительные затраты времени на преобразование данных функциями РеквизитФормыВЗначение -> ЗначениеВРеквизитФормы тестовая операция будет простой: изменение текста комментария документа конкатенированием на каждой итерации строки "1". Для тестрования используется самописный документ Квотация. В документе около 40 реквизитов и присутствует ТЧ Товары, но в тестовом документе заполнена всего лишь 1 строка, т.е. объем данных самого тестового документа относительно небольшой. Для каждого варианта кода выполняется 100 итераций. Замер выполняется для тонкого клиента в рамках локальной сети. При работе через браузер картинка для конечного пользователя скорее всего получится более печальной.

Тест 1. 100 вызовов на сервере

 

// в модуле объекта документа
Процедура РасширитьКомментарий() Экспорт
	Комментарий = Комментарий + "1";
КонецПроцедуры

// в модуле управляемой формы
&НаСервере
Процедура РасширитьКомментарий()
	Объект.Комментарий = Объект.Комментарий + "1";
КонецПроцедуры

&НаСервере
Процедура ТестВМодульФормыНаСервере()	
	Объект.Комментарий = "";
	Для Инд = 0 По 99 Цикл	
		РасширитьКомментарий();
	КонецЦикла;	
КонецПроцедуры

&НаКлиенте
Процедура ТестВМодульФормы(Команда)
	ТестВМодульФормыНаСервере();	
	ПоказатьПредупреждение(, "Завершено!");
КонецПроцедуры

&НаСервере
Процедура ТестВМодульОбъектаНаСервере()	
	Объект.Комментарий = "";
	Для Инд = 0 По 99 Цикл
		Документ = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Квотация"));
		Документ.РасширитьКомментарий();
		ЗначениеВРеквизитФормы(Документ, "Объект");	
	КонецЦикла;	
КонецПроцедуры

&НаКлиенте
Процедура ТестВМодульОбъекта(Команда)	
	ТестВМодульОбъектаНаСервере();
	ПоказатьПредупреждение(, "Завершено!");	
КонецПроцедуры

Замер производительности показал

Строка

Кол-во

Время

% Врем

ТестВМодульОбъектаНаСервере();

1

0.940744

89.09

Документ = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Квотация"));

100

0.741111

70.18

ТестВМодульФормыНаСервере();

1

0.082241

7.79

ЗначениеВРеквизитФормы(Документ, "Объект");

100

0.077764

7.36

ПоказатьПредупреждение(, "Завершено!");

1

0.026787

2.54

ПоказатьПредупреждение(, "Завершено!");

1

0.006109

0.58

Документ.РасширитьКомментарий();

100

0.002946

0.28

РасширитьКомментарий();

100

0.001812

0.17

Объект.Комментарий = Объект.Комментарий + "1";

100

0.000912

0.09

Комментарий = Комментарий + "1";

100

0.000880

0.08

КонецЦикла;

100

0.000409

0.04

* здесь и далее в таблицах замеров приведена лишь шапка замера. Затраты менее 0.01 с. обрезаны

Тест 2. 100 вызовов сервера

 

// в модуле объекта документа
Процедура РасширитьКомментарий() Экспорт
	Комментарий = Комментарий + "1";
КонецПроцедуры

// в модуле управляемой формы
&НаСервере
Процедура РасширитьКомментарий()
	Объект.Комментарий = Объект.Комментарий + "1";
КонецПроцедуры

&НаСервере
Процедура ТестВМодульФормыНаСервере()
	
	РасширитьКомментарий();
	
КонецПроцедуры

&НаКлиенте
Процедура ТестВМодульФормы(Команда)
	Объект.Комментарий = "";
	Для Инд = 0 По 99 Цикл
		ТестВМодульФормыНаСервере();
	КонецЦикла;
	ПоказатьПредупреждение(, "Завершено!");
КонецПроцедуры

&НаСервере
Процедура ТестВМодульОбъектаНаСервере()
	
	Документ = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Квотация"));
	Документ.РасширитьКомментарий();
	ЗначениеВРеквизитФормы(Документ, "Объект");	
	
КонецПроцедуры

&НаКлиенте
Процедура ТестВМодульОбъекта(Команда)
	Объект.Комментарий = "";
	Для Инд = 0 По 99 Цикл
		ТестВМодульОбъектаНаСервере();
	КонецЦикла;
	ПоказатьПредупреждение(, "Завершено!");
КонецПроцедуры

Замер производительности показал

Строка

Кол-во

Время

% Врем

ТестВМодульОбъектаНаСервере();

100

7.786877

52.38

ТестВМодульФормыНаСервере();

100

6.145152

41.33

Документ = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Квотация"));

100

0.998177

6.71

КонецЦикла;

100

0.502597

3.38

КонецЦикла;

100

0.401119

2.70

ЗначениеВРеквизитФормы(Документ, "Объект");

100

0.090248

0.61

ТекущийРежим = СоединенияИБ.ПараметрыБлокировкиСеансов();

1

0.014858

0.10

ПоказатьПредупреждение(, "Завершено!");

1

0.009055

0.06

ПоказатьПредупреждение(, "Завершено!");

1

0.006647

0.04

РасширитьКомментарий();

100

0.003752

0.03

Документ.РасширитьКомментарий();

100

0.003544

0.02

Объект.Комментарий = Объект.Комментарий + "1";

100

0.002546

0.02

Комментарий = Комментарий + "1";

100

0.001131

0.01


Т.е. в данном случае затраты на вызов РеквизитФормыВЗначение присутствуют, но значительно больше времени уходит на каждый вызов сервера с клиента.

Бонус. Тест 3. 100 вызовов на сервере для большого документа

В документе содержится 568 строк в ТЧ Товары. Результаты замеров:

 

Строка

Кол-во

Время

% Врем

ТестВМодульОбъектаНаСервере();

1

16.831681

98.45

Документ = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Квотация"));

100

10.072014

58.91

ЗначениеВРеквизитФормы(Документ, "Объект");

100

3.866123

22.61

ТестВМодульФормыНаСервере();

1

0.228471

1.34

ТекущийРежим = СоединенияИБ.ПараметрыБлокировкиСеансов();

1

0.017236

0.10

ПоказатьПредупреждение(, "Завершено!");

1

0.010469

0.06

ПоказатьПредупреждение(, "Завершено!");

1

0.008086

0.05

Документ.РасширитьКомментарий();

100

0.004518

0.03

РасширитьКомментарий();

100

0.001549

0.01

Комментарий = Комментарий + "1";

100

0.001333

0.01

Объект.Комментарий = Объект.Комментарий + "1";

100

0.000767

0.00

КонецЦикла;

100

0.000596

0.00

 

Итоги

Разумное использование связки функций РеквизитФормыВЗначение - ЗначениеВРеквизит формы более чем уместно, т.к. позволит устранить дублирование кода при относительно малых затратах (0,007-0,009 с. за вызов). Однако, использовние этой связки лучше избегать в следующих случаях:

1. Вызов осуществляется в цикле (например, при обработке ТЧ)

2. Документ имеет очень сложную структуру с одной или несколькими ТЧ, которые могут содержать несколько десятков и более записей.

Вступайте в нашу телеграмм-группу Инфостарт

производительность РеквизитФормыВЗначение ДанныеФормыВзначение ЗначениеВРеквизитФормы замер производительности

См. также

Механизмы платформы 1С Программист Бесплатно (free)

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    18123    TitanLuchs    101    

128

Механизмы платформы 1С WEB-интеграция Программист 1С v8.3 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    17914    dsdred    77    

129

Механизмы платформы 1С Программист Стажер 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    19363    bayselonarrend    22    

168

HighLoad оптимизация Инструменты администратора БД Системный администратор Программист 1С v8.3 1C:Бухгалтерия Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

5 стартмани

15.02.2024    17317    321    ZAOSTG    100    

122

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    28541    SeiOkami    48    

139

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист 1С v8.3 1C:Бухгалтерия Бесплатно (free)

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

28.08.2023    21072    YA_418728146    8    

174

Механизмы платформы 1С Программист 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    40208    SeiOkami    33    

124
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dgolovanov 02.07.15 13:04 Сейчас в теме
СокрЛП(Статья): Стоит ли использовать РеквизитФормыВЗначение? В одних ситуация - да, в других - нет.
Kreitr; GATTUSO; Sheff; nixel; DrAku1a; sergelemon; Irwin; y22-k; charushkin; anchovy; jobkostya1c_ERP; pavlov_dv; ixijixi; +13 Ответить
2. EmpireSer 02.07.15 13:09 Сейчас в теме
Я как-то считал очевидным такие накладные расходы на создание прикладного объекта из структур данных формы (ДанныеФормыСтруктура, ДанныеФормыКолекция и т.д.)

Если необходимо обеспечить работу и обычной и управляемой формы, то лучше это выносить в общий модуль с соответствующим контекстом исполнения. Тогда не будет дубликатов кода.
3. arancar 19 02.07.15 13:17 Сейчас в теме
(2) EmpireSer, Можно, но как Вы видите передачу контекста? Другие варианты кроме передачи кучи возвращаемых параметров или структуры с необходимыми данными можете предложить? Буду признателен за конструктив
5. EmpireSer 02.07.15 13:36 Сейчас в теме
(3)
Контекст - это сервер, клиент (управляемые формы), клиент (обычные формы).

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

К примеру вот код:
// Дополняет таблицу-приемник данными из таблицы-источник.
//
// Параметры:
//  ТаблицаПриемник - Таблица - таблица, в которую будут добавлены строки из таблицы-источника;
//  ТаблицаИсточник - Таблица - таблица, из которой будут браться строки для заполнения.
Функция ТаблицаДополнить(Знач ТаблицаПриемник, Знач ТаблицаИсточник) Экспорт
	Для Каждого СтрокаТаблицыИсточник Из ТаблицаИсточник Цикл
		ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаТаблицыИсточник);
	КонецЦикла;
	
	Возврат ТаблицаПриемник;
КонецФункции
Показать

Этому коду без разницы что в него подать: ТаблицаЗначений, ТабличнаяЧасть, Регистр...НаборЗаписей, ДанныеФормыКоллекция, ДанныеФормыСтруктураСКоллекцией. И Контекст не важен, т.к. у всех этих объектов метод "Добавить" существует как на клиенте так и на сервере.

Или к примеру нам нужно найти в ТабличнойЧасти объекта какие-то строки (найти номенклатуру в табличной части Товары документа), то метод "НайтиСтроки" существует и у ТабличнаяЧасть и у ДанныеФормыКоллекция. И это означает, что код может быть универсален.

Вот про что я говорил.
6. arancar 19 02.07.15 15:28 Сейчас в теме
(5) EmpireSer, при использовании Знач ТаблицаПриемник Вы не увидите изменений в начальной таблице, разве нет? В целом идея понятна, но это упрощенный вариант. Толчком к моим размышлениям послужил метод ПриИзмененииДоговора. Вчера он, допустим, менял Валюту и КодУсловийОплаты, а завтра понадобилось дополнительно менять ДнейОтсрочки, т.е. для внесения изменений в новый реквизит. При использовании частичной передачи контекста в ОМ этот контекст придется постоянно расширять, т.е. вносить изменения не только в саму функцию, но и в каждый вызов самой функции. Это мне и не нравится
7. EmpireSer 02.07.15 20:56 Сейчас в теме
(6)

1. Про "Знач" лучше читайте ИТС. Я плохо могу объяснять разницу между объектным типом и простым.
Пример я привёл из своего общего модуля, где все методы созданы как функции для обхода отсутствия поддержки в веб-клиенте метода "Выполнить". Ну это отдельная песня...

2. Когда мне нужна супер гибкость я просто в метод общего модуля передам "ЭтаФорма" и при написании кода буду учитывать отличия между методами объектов, которые я обрабатываю. Это я Вам и предложил и тем самым Вам не нужно будет увеличивать количество передаваемых параметров в метод общего модуля.
8. anchovy 24 06.07.15 11:55 Сейчас в теме
(6) Изменений исходной таблицы не увидит, и это хорошо в данном случае. Достаточно будет возвращенного результата функции.
4. EmpireSer 02.07.15 13:20 Сейчас в теме
Вообще если пишете внешнюю обработку, то необходимость написать общий код в модуле объекта возрастает значительно. Но если применить хитрость, то накладные расходы будут нулевые:
1. В обработке не создавать ни каких реквизитов
2. В общей форме и в управляемой форме все необходимые реквизиты будут заданы (т.е. они будут реквизитами формы)
3. В модуле обработки методы принимают параметр "Данные", который по сути есть передача ЭтаФорма.
Для отправки сообщения требуется регистрация/авторизация