Каталог решений - Ускорение медленной работы строк в 1С на примере 1С:Документооборот КОРП

Ускорение медленной работы строк в 1С на примере 1С:Документооборот КОРП

Ускорение медленной работы строк в 1С на примере 1С:Документооборот КОРП

В наличии

Если у вас в 1С:Документооборот КОРП 2.1.11.5 (часть более старых и новых конфигураций):
1) Долго отправляется почта в формате HTML;
2) Медленно открывается документы внутренние / входящие / исходящие;
3) Тормозит область просмотра или открытие задач.
Тогда вам сюда.

Категория:

Описание

Типовые конфигурации 1С умеют показать — как делать не надо.

Что может быть опасного в выражениях работы со строками или символами, например:

Строка = Строка + Символ;
КодСимвола(Строка, Позиция);
Символ = Символ(Код);

Пусть даже это происходит в цикле, ведь одна операция выполняется 0,5-2 миллисекунды.

Допустим, в такой типовой функции, которая часто используется в различных блоках конфигурации.

Функция ЗаменитьСпецСимволыHTML(Строка, СпецСимволыСоотв = Неопределено) Экспорт
	СоответствиеСпецСимволов = РаботаС_HTMLПовтИсп.ПолучитьСоответствиеСпецСимволов();
	ЗаменитьСпецСимволHTML(Строка, 38, "amp");
	НоваяСтрока = "";
	
	Для Поз = 1 По СтрДлина(Строка) Цикл
		Код = КодСимвола(Строка, Поз);
		ИмяСимвола = СоответствиеСпецСимволов.Получить(Код);
		
		Если ИмяСимвола = Неопределено Тогда
			НоваяСтрока = НоваяСтрока + Символ(Код);
		Иначе
			НоваяСтрока = НоваяСтрока + "&" + ИмяСимвола + ";";
		КонецЕсли;
	КонецЦикла;

	Строка = НоваяСтрока;
	Возврат Строка;
КонецФункции

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

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

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

  1. Получаем "код символа".
  2. Ищем "имя символа" в соответствии.
  3. Добавить к строке символ, если "имя символа":
    1. тогда добавить "символ" по коду символа;
    2. иначе добавить "имя символа".

Вроде все логично, проверяем символы и если необходимо, производим замену.

Но вот идеи, что можно сделать:

  1. Зачем переводить символ в код и обратно пункты 1. и 3.1., надо получать символ, а от него код, тогда не надо получать символ по коду.
  2. Сделать КЭШ в котором хранились символы, по которым была выполнена проверка и результат поиска.
  3. Пункт 3.1 будет выполнять подряд несколько раз, если не было спец. символов, значит надо накапливать строку и добавлять целиком, а не по одному символу. 

Посмотрим, что у нас получилось

Функция ЗаменитьСпецСимволыHTML(Строка, СпецСимволыСоотв = Неопределено) Экспорт
	
	СоответствиеСпецСимволов = РаботаС_HTMLПовтИсп.ПолучитьСоответствиеСпецСимволов();
	ЗаменитьСпецСимволHTML(Строка, 38, "amp");
	НоваяСтрока = "";
	
	// {{ новый алгоритм
	КЭШ_Символов = Новый Соответствие;
	Последний = 0;

	Для Поз = 1 По СтрДлина(Строка) Цикл
		Символ = Сред(Строка, Поз, 1);
		ИмяСимвола = КЭШ_Символов.Получить(Символ);
		
		Если ИмяСимвола = Неопределено Тогда 
			Код = КодСимвола(Строка, Поз);
			ИмяСимвола = СоответствиеСпецСимволов.Получить(Код);
			
			Если ИмяСимвола = Неопределено Тогда
				ИмяСимвола = "Неопределено";
			КонецЕсли;
			
			КЭШ_Символов.Вставить(Символ, ИмяСимвола);
		КонецЕсли;
			
		Если ИмяСимвола <> "Неопределено" Тогда 
			Если Последний = 0 Тогда 
				ПодСтрока = "";
			Иначе 
				ПодСтрока = Сред(Строка, Последний, Поз - Последний);
				Последний = 0;
			КонецЕсли;
			
			НоваяСтрока = НоваяСтрока + ПодСтрока + "&" + ИмяСимвола + ";";
		ИначеЕсли Последний = 0 Тогда 
			Последний = Поз;
		КонецЕсли;
	КонецЦикла;
	
	Строка = НоваяСтрока + ?(Последний = 0, "", Сред(Строка, Последний, Поз - Последний + 1));
	// }} новый алгоритм
	
	Возврат Строка;
КонецФункции

Давайте посмотрим, как изменился замер производительности

О чудо стало работать почти в 100 раз быстрее.

 

PS: Часто программисты не пытаются решить проблемы логики, а пытаются решить проблему медленных механизмов.

Но как показывает практика — исправление логики приносит более значимый результат.

 

Update (2020-10-02 15:15):

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

В типовом релизе 1С:Документооброт ПРОФ 2.0.14.4 используют процедуру "ЗаменитьСпецСимволHTML()", но с ней есть проблема.

Значение символа по коду "Символ(КодСимвола)" вычисляется долго.

Но кто нам мешает объединить все лучшее в одном месте.

Функция ЗаменитьСпецСимволыHTML(Строка, СпецСимволыСоотв = Неопределено) Экспорт
	СоответствиеСпецСимволов = РаботаС_HTMLПовтИсп.ПолучитьСоответствиеСпецСимволов();
	ЗаменитьСпецСимволHTML(Строка, 38, "amp");
	
	// {{ новый алгоритм (4)
	Для Каждого СпецСимвол Из СоответствиеСпецСимволов Цикл 
		Строка = СтрЗаменить(Строка, РаботаС_HTMLПовтИсп.ПолучитьСимволПоКоду(СпецСимвол.Ключ), "&" + СпецСимвол.Значение + ";");
	КонецЦикла;
	// }} новый алгоритм (4)
	
	Возврат Строка;
КонецФункции

и в общем в подходящем общем модуле, добавил функцию для повторного использования.

Функция ПолучитьСимволПоКоду(Код) Экспорт
	Возврат Символ(Код);
КонецФункции

Итого: При первом использовании время немного больше 1 сек, но при повторном использовании время падает до 0,05 сек!

has been added to your cart:
Оформление заказа