Содержание:
1. Ключевые техники рефакторинга для повышения производительности 1С
2. Безопасный процесс рефакторинга
Рефакторинг — это мощный инструмент не только для наведения порядка, но и для прямой оптимизации.
В мире разработки на 1С: Предприятие часто можно услышать фразу: «Работает — не трогай». Этот подход может быть оправдан в краткосрочной перспективе, но в долгосрочной он неизбежно приводит к накоплению «технического долга» — запутанного, неэффективного и сложного в поддержке кода. Именно такой код чаще всего становится причиной проблем с производительностью.
Здесь на помощь приходит рефакторинг — процесс улучшения внутренней структуры существующего кода без изменения его внешнего поведения. В контексте производительности рефакторинг — это не просто «причесывание» кода, а целенаправленная переработка неэффективных участков для их кардинального ускорения.
Важно понимать ключевое отличие:
- Исправление ошибки (багфикс) — это изменение кода, чтобы он начал работать правильно.
- Рефакторинг — это изменение кода, который уже работает правильно, с целью сделать его более понятным, поддерживаемым и, в нашем случае, более быстрым.
Ключевые техники рефакторинга для повышения производительности 1С
Проблемы с производительностью редко бывают уникальными. Чаще всего они вызваны одними и теми же архитектурными ошибками. Рассмотрим основные техники рефакторинга для их устранения.
1. Замена запроса в цикле на пакетный запрос (Extract Loop to Query)
Это самый мощный и часто применяемый рефакторинг. Он направлен на искоренение проблемы «N+1 запросов».
- «Запах» кода (Code Smell): Внутри цикла по результатам одного запроса происходит обращение к базе данных.
- Пример «до» рефакторинга
// ПЛОХО: Неэффективно и медленно
// Когнитивная сложность: 1 | Цикломатическая сложность: 2
Процедура ОбновитьЦеныНоменклатуры()
Запрос = Новый Запрос(“ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ЭтоГруппа = ЛОЖЬ”);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Для каждой номенклатуры отдельным запросом получаем последнюю цену
ПоследняяЦена = РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(ТекущаяДата(),
Новый Структура(“Номенклатура”, Выборка.Ссылка));
// … какая-то логика
КонецЦикла;
КонецПроцедуры
- Пример «после» рефакторинга:
// ХОРОШО: Все данные получаются одним запросом
// Когнитивная сложность: 1 | Цикломатическая сложность: 2
Процедура ОбновитьЦеныНоменклатуры()
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ЦеныНоменклатурыСрезПоследних.Номенклатура,
| ЦеныНоменклатурыСрезПоследних.Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ) КАК ЦеныНоменклатурыСрезПоследних”;
Запрос.УстановитьПараметр(“Дата”, ТекущаяДата());
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из Результат Цикл
// … вся логика выполняется с уже полученными данными
КонецЦикла;
КонецПроцедуры
2. Извлечение метода (Extract Method)
Длинные, монолитные процедуры и функции сложны для понимания, отладки и оптимизации. Разделение их на небольшие, логически завершенные подпрограммы не только улучшает читаемость, но и позволяет точечно оптимизировать производительность.
- «Запах» кода: Процедура на несколько экранов, содержащая разные логические блоки.
- Рефакторинг: Выделите логически обособленный фрагмент кода в отдельную процедуру или функцию. Это позволит, например, заменить неэффективный блок кода на более производительный аналог, не затрагивая остальную логику. Кроме того, это помогает выявить и кешировать повторяющиеся вычисления.
3. Кеширование результатов вычислений (Cache Result)
Некоторые функции вызываются многократно с одними и теми же параметрами, каждый раз выполняя ресурсоемкие вычисления.
- «Запах» кода: Многократный вызов одной и той же функции с одинаковыми параметрами внутри одной операции.
- Пример «до» рефакторинга:
// ПЛОХО: Функция будет вызвана много раз для одного и того же курса
Для Каждого Строка Из ТаблицаТоваров Цикл
Строка.СуммаВВалюте = Строка.Сумма / ПолучитьКурсВалюты(Строка.Валюта, ДатаДокумента);
КонецЦикла;
- Пример «после» рефакторинга:
// ХОРОШО: Курсы кешируются в соответствии, которое можно заполнить курсами сразу
КешированныеКурсы = Новый Соответствие;
Для Каждого Строка Из ТаблицаТоваров Цикл
Курс = КешированныеКурсы.Получить(Строка.Валюта);
Если Курс = Неопределено Тогда
Курс = ПолучитьКурсВалюты(Строка.Валюта, ДатаДокумента);
КешированныеКурсы.Вставить(Строка.Валюта, Курс);
КонецЕсли;
Строка.СуммаВВалюте = Строка.Сумма / Курс;
КонецЦикла;
- Этот подход позволяет выполнить дорогостоящую операцию получения курса для каждой валюты только один раз.
Безопасный процесс рефакторинга
Рефакторинг без «страховочной сетки» — опасное занятие. Чтобы не сломать работающий функционал, процесс должен быть строго регламентирован.
- Измерьте «до»: Прежде чем что-то менять, зафиксируйте текущую производительность. Используйте «Замер производительности» или Технологический журнал, чтобы получить объективные цифры.
- Напишите тесты: Идеальный сценарий — наличие автоматизированных тестов (например, с помощью Vanessa-Automation), которые проверяют корректность работы изменяемого функционала. Если их нет, составьте детальный ручной сценарий проверки.
- Выполните рефакторинг: Примените одну из техник, изменяя код небольшими, контролируемыми шагами.
- Протестируйте: Запустите тесты (автоматические или ручные) и убедитесь, что внешнее поведение кода не изменилось.
- Измерьте «после»: Снова замерьте производительность. Только если вы видите реальное улучшение, рефакторинг можно считать успешным.
Вывод:
Рефакторинг — это не разовое мероприятие, а постоянная гигиена кода. Внедрение практик рефакторинга в ежедневную работу позволяет не только исправлять существующие проблемы с производительностью, но и предотвращать их появление в будущем. Код, который легко читать и понимать, гораздо проще сделать быстрым. Это прямая инвестиция в стабильность, скорость и долгосрочную ценность вашей информационной системы.
Специалист компании ООО “Кодерлайн”,
Радченко Степан
Добавить комментарий