Top.Mail.Ru
Full-time, 5/2
Формат: удаленный
Вакансия «1С-программист»

Очистка табличного документа на клиенте. Миф или реальность?

Введение

Рано или поздно все программисты 1С сталкиваются с необходимостью повторного использования табличного документа после его заполнения, например, для реквизита формы с типом ТабличныйДокумент на форме отчета. По справке 1С, для этого есть метод ТабличныйДокумент.Очистить(), который доступен только на сервере.

А что делать, если понадобилось очистить его на клиенте?
Или, может, так было бы оптимальнее, с точки зрения клиент-серверного взаимодействия?
Пустой табличный документ явно проще передать на сервер, чем заполненный (а они бывают больших размеров), разве нет?

Вопросы к процессу

На клиенте реквизит очистить можно, с этим прекрасно справляются
ТабличныйДокумент = Неопределено  
или
ТабличныйДокумент = Новый ТабличныйДокумент

Но тут возникают вопросы:

  1. А не происходит ли неявный серверный вызов в таком случае?
  2. А это будет быстрее, чем ТабличныйДокумент.Очистить()?

Отвечая на первый вопрос, нет, серверный вызов не происходит, счетчик вызовов остается на отметке 0.
Отвечая на второй, при условии, что очищается уже заполненный табличный документ, то очистка на сервере явно проигрывает (на клиенте очистка почти всегда 0 мс), особенно учитывая тот факт, что для этого необходим серверный вызов, который итак стоит ресурсов.

Казалось бы, классное решение, может, его тогда везде использовать? Странно, что разработчики фирмы 1С в типовых решениях не используют этот способ. Или, возможно, все не так однозначно?

Переходим к цифрам

Замеры производились на табличном документе 500 000 строк х 20 колонок с текстом в ячейках «PROSTO». Все результаты приведены в усредненных значениях.

Для начала покажу результаты сравнения очистки на клиенте и на сервере (без учета серверного вызова).

Отличный результат, хоть и 0.2 секунды для огромного табличного документа не кажутся ощутимым приростом, но почему бы и нет. Реализация же очень простая.

А теперь проверим этот способ в условиях, близких к реальным. Очищаем табличный документ и формируем новый на сервере, точно такой же, как и был до этого (переформировываем отчет). Заполнение табличного документа в замеры не включается.

Код

Код с очисткой на клиенте:

&НаКлиенте
Процедура ОчисткаНаКлиенте(Команда)
    
    Событие = "Очистка на клиенте";
    НачалоЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах();
    
    ТабличныйДокумент = Неопределено;
    
    ЗафиксироватьЗамер(НачалоЗамера, Событие);
    
    НачалоЗамераСерверногоВызова = ТекущаяУниверсальнаяДатаВМиллисекундах();
    НачалоВозвратаССервера = ПерезаполнитьНаСервереБезОчистки(НачалоЗамераСерверногоВызова);
    
    Событие = "ЗаполнитьНаСервереОчиститьНаКлиенте: Сервер -> Клиент";
    ЗафиксироватьЗамер(НачалоВозвратаССервера, Событие);
    
КонецПроцедуры

&НаСервере
Функция ПерезаполнитьНаСервереБезОчистки(НачалоЗамера)
    
    Событие = "ЗаполнитьНаСервереОчиститьНаКлиенте: Клиент -> Сервер";
    ЗафиксироватьЗамер(НачалоЗамера, Событие);
    
    ЗаполнитьНаСервере();
    
    Возврат ТекущаяУниверсальнаяДатаВМиллисекундах();
    
КонецФункции

Код с очисткой на сервере:

&НаКлиенте
Процедура ОчисткаНаСервере(Команда)
    
    НачалоЗамераСерверногоВызова = ТекущаяУниверсальнаяДатаВМиллисекундах();
    НачалоВозвратаССервера = ПерезаполнитьНаСервереСОчисткой(НачалоЗамераСерверногоВызова);
    
    Событие = "ЗаполнитьНаСервереОчиститьНаСервере: Сервер -> Клиент";
    ЗафиксироватьЗамер(НачалоВозвратаССервера, Событие);
    
КонецПроцедуры

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

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

Вопросы к временному промежутку

Почему передача пустого табличного документа занимает больше времени, чем заполненного?

Полагаю, что это из-за того, что контекстный серверный вызов понимает, что неизменённый табличный документ ни к чему переносить на сервер: там он точно такой же. В итоге перенос пустого табличного документа только прибавляет нагрузки при передаче на сервер, но это компенсируется временем очистки.

А почему возврат одного и того же табличного документа на клиент занимает разное время?

К сожалению, тут у меня нет предположений. Может, это из-за того, что табличный документ возвращается идентичный тому, что был до переформирования? Но нет, смена текста ячеек ни к чему не привела. Результат остался тем же.

 Выводы

Использовать очистку на клиенте можно, но только в крайне ограниченном варианте. Допустим, если вы по какой-то неведомой причине используете только клиентские и серверные вызовы без контекста в работе с табличным документом. Но даже в таком случае выгода крайне сомнительна.

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar