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

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. Документ имеет очень сложную структуру с одной или несколькими ТЧ, которые могут содержать несколько десятков и более записей.

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

См. также

Планы обмена VS История данных

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

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6897    dsdred    36    

113

1С-ная магия

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

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

06.10.2023    18971    SeiOkami    46    

118

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    9309    YA_418728146    6    

143

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

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

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

27.06.2023    16668    SeiOkami    31    

104

MS SQL Server: изучаем планы запросов

Запросы HighLoad оптимизация Запросы Бесплатно (free)

Многие знают, что для ускорения работы запроса нужно «изучить план». При этом сам план обычно обескураживает: куча разноцветных иконок и стрелочек; ничего не понятно, но очень интересно! Аналитик производительности Александр Денисов на конференции Infostart Event 2021 Moscow Premiere рассказал, как выполняется план запроса и что нужно сделать, чтобы с его помощью находить проблемы производительности.

20.06.2023    16873    Филин    37    

114

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

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

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    7110    SeiOkami    10    

140

Версионирование объектов VS История данных

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

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    19739    dsdred    54    

195
Комментарии
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
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. В модуле обработки методы принимают параметр "Данные", который по сути есть передача ЭтаФорма.
Оставьте свое сообщение