Типовые конфигурации 1С умеют показать - как делать не надо.
Что может быть опасного в выражениях работы со строками или символами, например:
Строка = Строка + Символ;
КодСимвола(Строка, Позиция);
Символ = Символ(Код);
Пусть даже это происходит в цикле, ведь одна операция выполняется 0,5-2 миллисекунды.
Допустим, в такой типовой функции, которая часто используется в различных блоках конфигурации.
Функция ЗаменитьСпецСимволыHTML(Строка, СпецСимволыСоотв = Неопределено) Экспорт
СоответствиеСпецСимволов = РаботаС_HTMLПовтИсп.ПолучитьСоответствиеСпецСимволов();
ЗаменитьСпецСимволHTML(Строка, 38, "amp");
НоваяСтрока = "";
Для Поз = 1 По СтрДлина(Строка) Цикл
Код = КодСимвола(Строка, Поз);
ИмяСимвола = СоответствиеСпецСимволов.Получить(Код);
Если ИмяСимвола = Неопределено Тогда
НоваяСтрока = НоваяСтрока + Символ(Код);
Иначе
НоваяСтрока = НоваяСтрока + "&" + ИмяСимвола + ";";
КонецЕсли;
КонецЦикла;
Строка = НоваяСтрока;
Возврат Строка;
КонецФункции
Но если длина строки измеряется тысячами и десятками тысячами символов, то несложно догадаться, что это займет уже секунды, десятки секунд, а может даже и сотни, что у нас и случилось.
Кажется, надо срочно выбрать другой тип переменной, отличный от строки, или использовать другие механизмы и объекты.
Но давайте попробуем понять, что там происходит в цикле, зачем и что с этим можно сделать.
- Получаем "код символа".
- Ищем "имя символа" в соответствии.
- Добавить к строке символ, если "имя символа":
- тогда добавить "символ" по коду символа;
- иначе добавить "имя символа".
Вроде все логично, проверяем символы и если необходимо, производим замену.
Но вот идеи, что можно сделать:
- Зачем переводить символ в код и обратно пункты 1. и 3.1., надо получать символ, а от него код, тогда не надо получать символ по коду.
- Сделать КЭШ в котором хранились символы, по которым была выполнена проверка и результат поиска.
- Пункт 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 сек!