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

02.10.20

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

Если у вас в 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 сек!

Долго Медленно Тормозит УСКОРЕНИЕ Оптимизация Документооброт Строка HTML доработка типовых КОРП избыточное

См. также

Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы

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

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    3581    spyke    28    

47

Быстродействие типовой 1С

HighLoad оптимизация Платформа 1С v8.3 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    5536    vasilev2015    19    

38

Анализируем SQL сервер глазами 1С-ника

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

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

1 стартмани

15.02.2024    8284    168    ZAOSTG    74    

101

Удаление строк из таблицы значений различными способами с замером производительности

HighLoad оптимизация Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Встал вопрос: как быстро удалить строки из ТЗ? Рассмотрел пять вариантов реализации этой задачи. Сравнил их друг с другом на разных объёмах данных с разным процентом удаляемых строк. Также сравнил с выгрузкой с отбором по структуре.

09.01.2024    6556    doom2good    48    

64

Опыт оптимизации 1С на PostgreSQL

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

При переводе типовой конфигурации 1C ERP/УТ/КА на PostgreSQL придется вложить ресурсы в доработку и оптимизацию запросов. Расскажем, на что обратить внимание при потерях производительности и какие инструменты/подходы помогут расследовать проблемы после перехода.

20.11.2023    9388    ivanov660    6    

76

ТОП проблем/задач у владельцев КОРП лицензий 1С на основе опыта РКЛ

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

Казалось бы, КОРП-системы должны быть устойчивы, быстры и надёжны. Но, работая в рамках РКЛ, мы видим немного другую картину. Об основных болевых точках КОРП-систем и подходах к их решению пойдет речь в статье.

15.11.2023    5344    a.doroshkevich    20    

72

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

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

11.10.2023    16593    skovpin_sa    14    

101
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. gabrielyants 01.10.20 23:36 Сейчас в теме
Спасибо за статью, неплохой вариант решения проблемы!
Sla; pavelpribytkin96; karpik666; BuildSolution; +4
2. Sedaiko 578 02.10.20 09:39 Сейчас в теме
Должно еще ускорится если заменить
НоваяСтрока = НоваяСтрока + ПодСтрока + "&" + ИмяСимвола + ";";
на
МассивНовыхСтрок.Добавить(ПодСтрока + "&" + ИмяСимвола + ";")
и в и после уже соединить
НоваяСтрока=СтрСоединить(МассивНовыхСтрок,"")

СтрСоединить специально для этого и ввели, чтобы ускорить конкатенацию
Поручик; simonovich; cosmo2004; +3
5. Iaskeliainen 385 02.10.20 14:24 Сейчас в теме
(2) Проверил данный вариант, получилось выиграть еще 1/3 времени. То есть за 0,6 сек.
Далее можно углубиться в повторное использование
	// {{ новый алгоритм (2)
	КЭШ_Символов = Новый Соответствие;
	Последний = 0;
	МассивНовыхСтрок = Новый Массив;

	Для Поз = 1 По СтрДлина(Строка) Цикл
		Символ = Сред(Строка, Поз, 1);
		ИмяСимвола = КЭШ_Символов.Получить(Символ);
		
		Если ИмяСимвола = Неопределено Тогда 
			Код = КодСимвола(Строка, Поз);
			ИмяСимвола = СоответствиеСпецСимволов.Получить(Код);
			
			Если ИмяСимвола = Неопределено Тогда
				ИмяСимвола = "Неопределено";
			КонецЕсли;
			
			КЭШ_Символов.Вставить(Символ, ИмяСимвола);
		КонецЕсли;
			
		Если ИмяСимвола <> "Неопределено" Тогда 
			Если Последний = 0 Тогда 
				ПодСтрока = "";
			Иначе 
				ПодСтрока = Сред(Строка, Последний, Поз - Последний);
				Последний = 0;
			КонецЕсли;
			
			МассивНовыхСтрок.Добавить(ПодСтрока + "&" + ИмяСимвола + ";");
		ИначеЕсли Последний = 0 Тогда 
			Последний = Поз;
		КонецЕсли;
	КонецЦикла;
	
	Если Последний <> 0 Тогда 
		МассивНовыхСтрок.Добавить(Сред(Строка, Последний, Поз - Последний + 1) + "&" + ИмяСимвола + ";");
	КонецЕсли;
	
	Строка = СтрСоединить(МассивНовыхСтрок, "");
	// }} новый алгоритм (2)
Показать
Mechanist; +1
6. Iaskeliainen 385 02.10.20 14:53 Сейчас в теме
(5) добавил повторное использование, перенес
КодСимвола(Строка, Поз)
в модуль
РаботаС_HTMLПовтИсп


Получилось ускорить еще в 2 раза, до 0,35 сек.
+
3. Yashazz 4722 02.10.20 11:38 Сейчас в теме
Вещи-то в целом очевидные, но за эти две фразы
Часто программисты не пытаются решить проблемы логики, а пытаются решить проблему медленных механизмов

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

респект однозначно.
zabaluev; Iaskeliainen; +2
4. Iaskeliainen 385 02.10.20 13:55 Сейчас в теме
Коллеги подсказали, что в 1С:Документооброт ПРОФ 2.0.14.4 используется
Процедура ЗаменитьСпецСимволHTML(Строка, КодСимвола, ИмяСимвола)
	
	Строка = СтрЗаменить(Строка, Символ(КодСимвола), "&" + ИмяСимвола + ";");
	
КонецПроцедуры

организовал, через неё
	Для Каждого СпецСимвол Из СоответствиеСпецСимволов Цикл 
		ЗаменитьСпецСимволHTML(Строка, СпецСимвол.Ключ, СпецСимвол.Значение);
	КонецЦикла;

Время выросло на 10%, до 1 сек
+
8. Iaskeliainen 385 02.10.20 15:08 Сейчас в теме
(4) Добавление повторного использования
Символ(КодСимвола)

Добавила скорости до космических 0,05 сек.
Надо добавить в статью.
Mechanist; +1
9. Iaskeliainen 385 02.10.20 15:30 Сейчас в теме
(4) Ждем этот вариант в типовой конфигурации :-)
+
7. protexprotex 114 02.10.20 14:56 Сейчас в теме
Да. Правильно. Проблема зачастую лежит в плоскости кривизны рук, а не в проблеме "железо не тянет" :-)
+
10. BobNN 02.10.20 22:42 Сейчас в теме
(7)
Любые курсы программирования должны предваряться курсами программирования на программируемом калькуляторе.
(С) идея чур моя!!
+
11. nomad_irk 72 02.10.20 23:13 Сейчас в теме
(10) ....с замером производительности и мониторингом утилизации аппаратной части :)
+
12. FatPanzer 02.10.20 23:35 Сейчас в теме
(10) Да я как раз и начинал с МК-52...
+
13. protexprotex 114 03.10.20 08:59 Сейчас в теме
(10) Точно! Наш препод говорил - учу Вас программировать на ассемблере потому, что он развивает логическое мышление и главное развивает привычку оптимизировать код еще в момент его написания, а не потом когда код уже написан и работает медленно и чтобы его оптимизировать нужно все переписать.
Yashazz; +1
14. SlavaKron 05.10.20 08:27 Сейчас в теме
(13) А еще есть мнение, что Преждевременная оптимизация — корень всех (или большинства) проблем в программировании.
athena; Tyler Durden; +2
15. protexprotex 114 05.10.20 10:13 Сейчас в теме
(14) Это да. Согласен. Но и ваять а кагбы вышло - лишь бы работало - тоже не айс. Потом чтобы переделать структуру программы - лучше заново все переписать. в 1С это не так критично. А вот, например программа на c++ (или еще хуже на ассемблере) - там нет априори заданных объектов типа ТаблицаЗначений, СписокЗначений (STL - компоненты не в счет - они все же более узкоспециализированные) - там структуру не ту выбереш - и потом чтобы все это оптимизировать, то легче заново переписать. Все должно быть в меру.
+
16. ICeZm 22 12.10.20 14:20 Сейчас в теме
Спасибо за статью!
+
Оставьте свое сообщение