КЕЙС: Как мы ускорили обмены с 10 часов до нескольких минут
Если в Вашей компании используется обмен между информационной системой на платформе 1С:Предприятие 8 и сайтом, или вы интересуетесь приемами повышения производительности, то думаю, Вам будет интересно посмотреть, как мы решили следующую задачу.
Клиент обратился с проблемой неработающего обмена с сайтом.
В своей работе Заказчик использует информационную систему на основе «Управление торговлей ред. 11». Конфигурация регулярно выполняет обмен с сайтом. Обмен осуществляется через XML файлы и происходил очень долго. При выгрузке данных для сайта клиент столкнулся с тем, что скрипт загрузки со стороны сайта не успевал обработать выгруженные данные.
Чтобы улучшить ситуацию, Заказчик своими силами разбил выгрузку на порции. Но это не принесло полного решения проблемы.
Чтобы решить проблему, заказчик пригласил меня.
Если Вы не сталкивались с методами повышения производительности раньше, то отмечу, что так или иначе все сводится к нахождению «избыточной работы» и устранению ее.
Проблема оказалась комплексной. Со стороны 1С при выгрузке в файлы попадала избыточная информация. Т.е. передавалось больше данных, чем потом реально использовалось. А со стороны сайта модуль загрузки выполнял лишние действия.
Кроме этого, сама выгрузка, даже по небольшому количеству товаров, занимала длительное время.
Чтобы понять, «какая деятельность лишняя», нужно посмотреть максимально подробно, из чего состоит вся процедура выгрузки данных.
Замер производительности «отладчиком» операции «выгрузки» показал следующее распределение длительности между операциями. 80% времени выполнялся запрос, собирающий данные для выгрузки. Мне повезло, так как 80% времени означает, что если улучшить этот запрос, то можно не прилагать много усилий к другим операциям, ведь эффект на всю выгрузку будет виден сразу. Еще 14% процентов замера выгрузки проверялось какое-то условие. Возможно, на результаты замера свое влияние оказала посторонняя нагрузка (замер выполнялся не «в чистых условиях», на сервере работали и другие пользователи), но этот замер дал представление о проблеме.

Самой простой проблемой оказалось условие «Если». Полностью условие выглядело так:
Если Параметры.РежимПошаговойВыгрузки И НЕ Параметры.ВыгружатьКраткийПакетПредложенийВРежимеИзменений И НеОпределено = ВыгруженныеТовары.Найти(Параметры.ВыборкаЦен.Номенклатура) Тогда
Проблема заключалась в выражении ВыгруженныеТовары.Найти(Параметры.ВыборкаЦен.Номенклатура)
Здесь ВыгруженныеТовары — это массив позиций номенклатуры, выгружаемой на текущем шаге. Количество элементов задается в параметрах выгрузки и составляет 400. То есть количество невелико.
Данные этого массива в процедуре никак не использовались, поэтому было решено заменить массив на соответствие. Соответствие представляет собой индексированную коллекцию, и поиск по ней выполняется очень быстро.
В качестве ключа использовал ссылку на номенклатуру, а значение «Истина». После доработки условие стало выглядеть так:
Если Параметры.РежимПошаговойВыгрузки И НЕ Параметры.ВыгружатьКраткийПакетПредложенийВРежимеИзменений И НеОпределено = ВыгруженныеТовары[Параметры.ВыборкаЦен.Номенклатура] Тогда
и общее время по этому выражению составило 34 секунды.
Количество повторений этого фрагмента определяется исходным алгоритмом.
Вторым проблемным фрагментом по замеру является запрос, выполняющий сбор данных для выгрузки.
МассивРезультатовЗапроса = Запрос.ВыполнитьПакет();
В данном замере время его выполнения составило более 8 часов. Запрос представляет из себя пакет из более 30 запросов.
Часть данного запроса получается на основе схемы компоновки данных с применением отборов. Отбор накладывается по номенклатуре по условию «в группе». При компоновке макета компоновщик, по возможности, добавляет в результирующий запрос условия, соответствующие отбору.
Например, запрос такого вида:
ВЫБРАТЬ РАЗРЕШЕННЫЕ СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура, СвободныеОстаткиОстатки.Характеристика КАК Характеристика, СвободныеОстаткиОстатки.ВНаличииОстаток КАК ВНаличииОстаток, СвободныеОстаткиОстатки.ВРезервеОстаток КАК ВРезервеОстаток ПОМЕСТИТЬ ВремОстатки ИЗ РегистрНакопления.СвободныеОстатки.Остатки() КАК СвободныеОстаткиОстатки
после применения отбора примет такой вид:
ВЫБРАТЬ РАЗРЕШЕННЫЕ СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура, СвободныеОстаткиОстатки.Характеристика КАК Характеристика, СвободныеОстаткиОстатки.ВНаличииОстаток КАК ВНаличииОстаток, СвободныеОстаткиОстатки.ВРезервеОстаток КАК ВРезервеОстаток ПОМЕСТИТЬ ВремОстатки ИЗ РегистрНакопления.СвободныеОстатки.Остатки(,Номенклатура В ИЕРАРХИИ (&П)) КАК СвободныеОстаткиОстатки
После компоновки данных это условие добавилось к нескольким запросам с полем номенклатура. Данное условие плохо сказывается на скорости выполнения запросов.
Чтобы решить эту проблему, в исходный запрос схемы компоновки данных добавил запрос выборки номенклатуры во временную таблицу. И уже данные этой таблицы использовал в качестве фильтра в последующих запросах. Также настроил схему компоновки данных таким образом, чтобы отбор по номенклатуре применялся только для добавленного запроса выборки номенклатуры. После этих манипуляций результирующий запрос принял такой вид (фрагмент):
ВЫБРАТЬ Номенклатура.Ссылка ПОМЕСТИТЬ втНоменклатура ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.Ссылка В ИЕРАРХИИ(&П) ; ВЫБРАТЬ РАЗРЕШЕННЫЕ СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура, СвободныеОстаткиОстатки.Характеристика КАК Характеристика, СвободныеОстаткиОстатки.ВНаличииОстаток КАК ВНаличииОстаток, СвободныеОстаткиОстатки.ВРезервеОстаток КАК ВРезервеОстаток ПОМЕСТИТЬ ВремОстатки ИЗ РегистрНакопления.СвободныеОстатки.Остатки(,Номенклатура В (ВЫБРАТЬ т.Ссылка ИЗ втНоменклатура как т)) КАК СвободныеОстаткиОстатки
Также анализ запроса выявил и другие причины его медленного выполнения:
- Соединение с подзапросами
- Отсутствующие или неоптимальные индексы
- Излишняя выборка данных
В общем, классика жанра.
Решив данные проблемы в комплексе, удалось сократить время выполнения результирующего запроса при полной выгрузке до 78 секунд.
Говоря об оптимизации в теоретическом контексте, часто забывается, что в реальной жизни любая коммерческая работа должна быть рентабельна. Несколько запросов пакета еще имели потенциал для ускорения, но полученный результат полностью устроил клиента, и на этом мы остановились.

После оптимизации время полной выгрузки не превышает 5 минут. Время выгрузки тестовой группы из 15 товаров – несколько секунд (до оптимизации –1.5 минуты).
Заказчик остался очень доволен и сказал много теплых слов. Всегда приятно не просто сделать хорошо работу, но и услышать слова благодарности.
Надеюсь, мой опыт пригодится Вам, и Вы тоже сможете помочь решить подобные проблемы.
Запись опубликована автором admin в рубрике производительность, тюнинг с метками выгрузка, запрос, обмен, оптимизация. Добавьте в закладки постоянную ссылку.
1С:Предприятие 8. Замер производительности
Режим замера производительности позволяет разработчику оценивать скорость работы как всей конфигурации в целом, так и отдельной ее части. В этом режиме измеряется частота использования конкретных участков кода и скорость их выполнения.
Подобный анализ помогает выбирать наиболее оптимальный способ программной реализации алгоритмов работы системы, а также определять пути для повышения быстродействия прикладного решения.
Результат замера производительности представляет собой список ссылок на конкретные строки модуля, с указанием частоты их выполнения и длительности (абсолютного времени выполнения и относительного, в процентах от общего времени выполнения замеряемого участка):
Результаты замера можно видеть также непосредственно в окне с исходным текстом модуля. Щелчком мыши на выбранной строке списка можно прейти к тексту модуля, для которого на отдельном поле будет отображено количество вызовов и относительное время выполнения каждой строки:
Результаты замера могут быть отсортированы по любой из колонок, например, по количеству вызовов строки:
Кроме этого, режим замера производительности позволяет производить выборочное суммирование строк замера, для получения суммарных характеристик выполнения некоторых строк:
Дополнительной возможностью является включение в замер или исключение из замера времени выполнения вызываемых процедур и функций. Использование этой возможности позволяет получать картину замера, максимально приближенную к реальной, в случае, когда из замеряемого модуля вызываются внешние по отношению к нему, процедуры.
Разработчик может сохранить результаты замера в файл для последующего анализа и сравнения с результатами других замеров.
Оценка производительности работы кода
В этой статье мы научимся делать замеры производительности работы 1С: Предприятия. Оценку производительности можно выполнять как в целом для всего приложения, начиная с момента его запуска и заканчивая закрытием, так и отдельного куска кода, если Вы хотите замерить одно какое-то узкое место. Все примеры по замерам производительности я буду показывать на демонстрационной конфигурации «Управляемое приложение 1С».
Научимся делать замер производительности всего приложения в целом от начала работы, до конца. Для этого необходимо запустить 1С: Предприятие в режиме конфигуратор, и в меню Отладка выбрать пункт «Замер производительности»

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

Соглашаемся, запускаем отладку (клавиша F5) и работаем. Конфигуратор 1С в это время должен быть включен!
Подробно о работе с отладкой читайте в этой статье:
Отладка в конфигураторе 1С
После того как Вы все сделаете и закроете 1С: Предприятие в пользовательском режиме, то откроется окно замера производительности.

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

Что бы его снять, нужно опять нажать на этот пункт меню.
Узнаем, как делать замер производительности в конкретном месте кода. Для этого откроем модуль документа «Поступление Денег» и установим точки останова в начале процедуры проведения и в конце.


После этого запустим отладку и попытаемся провести документ Оплата, а когда первая точка останова сработает, перейдем в меню «Отладка», где нажимаем уже знакомую нам кнопку «Замер производительности»

После того как запустили замер производительности, нужно продолжить отладку с помощью соответствующей кнопки или клавиши F5. Как сработает вторая точка останова, вернемся в меню отладка и заново нажмем на кнопку «Замер производительности»
После этого откроется окно результатов замера, и форма в конфигураторе 1С приобретет следующий вид.
Разберемся с этим окном, для большей наглядности сделаем замер производительности для обработки замены товара в табличной части документа «Приход товара» 

Смотрите на последний рисунок, как видно, строк в таблице замера больше, чем строк в самом обработчике, который мы замеряли. Это потому что в таблицу замеров входят не только строки выделенного фрагмента кода, но и строки процедур и функций, которые в этом коде вызываются. В нашем случае это две функции ПолучитьТекущуюСтрокуТовары и ПолучитьЦенуТовар.
Строки 16,17, 20, 22 относятся к функции ПолучитьЦенуТовара, а строки 33,34 – ПолучитьТекущуюСтрокуТовары. Если мы кликнем по нужной строке мышкой, то перейдем на эту строку в модуле.
Разберем некоторые колонки:
«Кол» — в этой колонке указано сколько раз выполнялась данная строка
«Время чистое» — время в секундах, которое было потрачено на выполнение данной строки, в данном случае берется суммарное время, т.е. все время, когда строка вызывалась.
«% времени» — отношение «Время чистое» к общему времени выполнения замера. Причем за 100% принимается выполнение кода на клиент. Т.е. корректно эта колонка работает когда мы начали на клиенте и закончили на клиенте, а если мы начали на сервере, а закончили на клиенте, то результат может быть не всегда корректен.
На отображение в колонках «Время чистое» и «% времени» влияет флаг «Для вызова процедур и функций включать время выполнения». Этот флаг нужно включать, когда мы хотим показать время на вызов процедуры или функции.

После того как мы установили этот флаг, поменялись значения в колонках «Время» и «% времени». Т.е. мы увидели, сколько относительного и абсолютного времени в целом тратиться на эту строку
Стр.Цена = ПолучитьЦенуТовара(Объект.Дата, Стр.Товар);
Разберемся, откуда взялась цифра 98,64% – время выполнения этой строки.
Если сложить проценты времени на выполнение кода в процедуре ПолучитьЦенуТовара, а это строки 16, 17, 20 и 22, будет — 86,41 %, но на рисунке мы видим, что исполнение процедуры занимает 98,64 % общего времени. Где еще 98,64 – 86,41 = 12,23 процента? Посмотрите на предыдущий рисунок, 12.23% — это именно время на вызов серверной процедуры.
Таким образом, если установлен флаг «Для вызова процедур и функций включать время выполнения» то показывает относительное и абсолютное время выполнения и вызова процедуры или функции. В тоже время если этот флаг снят, то показывается время только на вызов метода. Поскольку вызов любой серверной процедуры или функции (без разницы в контексте она формы, или внеконтекстная) требует определенных затрат, то информации о продолжительности вызова метода может быть очень полезной.
С остальными колонками все более менее понятно. Колонка «Клиент» при помощи специальной пиктограммы указывает, что строка выполняется на клиенте. А колонка «Сервер» указывает, что строка выполняется на сервере. Колонка «Обр. сервер» указывает, что в данной строке происходит передача управления на сервер.
Так же имейте ввиду, что часть информации из таблицы замеров дублируется в модуле. Цифры процентов в этом случае идентичны цифрам, когда флаг «Для вызова процедур и функций включать время выполнения» снят.

И на последок отмечу, когда будите делать замеры тех или иных процессов, имейте ввиду что скорость выполнения зависит от многих факторов (загруженность процессора, оперативной памяти). Поэтому желательно делать несколько разных замеров, что бы вычислить среднюю величину и исключить случайные скачки.
Пять эффективных инструмента отладки
Я стараюсь как можно чаще выпускать различные интересные бесплатные статьи и видеоуроки. Поэтому буду очень рад, если Вы поддержите мой проект перечислив любую сумму:
Изучайте основы конфигурирования в 1С и учитесь программировать в «1С: Предприятии» с помощью моих книг: «Программировать в 1С за 11 шагов» и «Основы разработки в 1С: Такси»
Изучайте программирование в 1С в месте с моей книги «Программировать в 1С за 11 шагов»
- Книга написана понятным и простым языком — для новичка.
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Научитесь понимать архитектуру 1С;
- Станете писать код на языке 1С;
- Освоите основные приемы программирования;
- Закрепите полученные знания при помощи задачника;

Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Промо-код на скидку в 15% — 48PVXHeYu
Если Вам помог этот урок решить какую-нибудь проблему, понравился или оказался полезен, то Вы можете поддержать мой проект, перечислив любую сумму:
можно оплатить вручную:
Яндекс.Деньги — 410012882996301
Web Money — R955262494655
Вступайте в мои группы:
1с замер производительности время чистое в чем измеряется
Одним из важнейших ресурсов программного продукта является время выполнения его программного кода. Оно, наряду с такими показателями, как функциональные возможности, надежность, практичность, сопровождаемость и мобильность, определяет уровень качества программного продукта. В работе рассмотрен метод измерения времени выполнения программного кода с помощью таймера высокой точности High Precision Event Timer (HPET). Описан класс Stopwatch библиотеки классов FCL каркаса Framework, который работает с HPET и предоставляет удобный набор средств, используемых для измерения времени. Описаны специальные проблемно-ориентированные методы класса Stopwatch технологии .Net в операционной системе Microsoft Windows. Основным преимуществом класса Stopwatch является более точное измерение временных интервалов при наличии таймера высокой точности HPET. В качестве эксперимента исследуется время обработки массивов классов Array, List и ArrayList. Для данных классов исследуется: время формирования элементов массивов; время работы методов Reverse, которые переставляют элементы массивов в обратном порядке; время работы методов Sort, которые сортируют элементы массивов. Приведен программный код на объектно-ориентированном языке программирования C# для платформы .NET Framework.

методы класса
эксперимент
временная эффективность алгоритмов
измерение времени программного кода
1. Лохматов С.Ю., Светлов С.В., Калач Г.П. Методы измерения времени работы программы // Современные научные исследования и инновации. 2017. № 5 [Электронный ресурс]. URL: http://web.snauka.ru/issues/2017/05/83188 (дата обращения: 11.03.2021).
2. Хашковскии В.В., Лутай В.Н., Юрченко В.В. Сравнительная оценка времени выполнения программ на различных платформах / Известия ЮФУ. Техн. науки. 2009. С. 176–180.
3. Ефремов М.А., Кирьянчиков В.А. Разработка методики и программного средства для измерения времени выполнения фрагментов программного кода // Современное образование: содержание, технологии, качество. СПб, «ЛЭТИ» им. В.И. Ульянова. 2019. Т. 1. С. 403–405.
4. ГОСТ ИСО/МЭК 9126-2001 «Информационные технологии. Оценка программной продукции. Характеристики качества и руководства по их применению». Минск: Евразийский совет по стандартизации, метрологи и сертификации, 2006. 13 с.
5. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644904(v=vs.85).aspx (дата обращения: 11.03.2021).
6. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644905(v=vs.85).aspx (дата обращения: 11.03.2021).
7. Карчевская М.П., Рамбургер О.Л. Измерение времени выполнения программного кода в ОС Windows с использованием ИСР Lazarus // Задачи обработки больших данных в авиации: материалы II Всероссийской научно-практической конференции «Свободный полет – 2015». Жуковский. Уфа, 2016. С. 127–133.
8. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.diagnostics.stopwatch(v=vs.110).aspx (дата обращения: 11.03.2021).
9. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.timespan(v=vs.110).aspx (дата обращения: 11.03.2021).
10. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.array(v=vs.110).aspx (дата обращения: 11.03.2021).
11. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.collections.arraylist(v=vs.110).aspx (дата обращения: 11.03.2021).
12. Карчевская М.П., Кузьмина Е.А., Рамбургер О.Л., Смирнова Е.А. Технология программирования на С#: учебное пособие. Уфа: РИК УГАТУ, 2016. 278 с.
13. Карчевская М.П., Рамбургер О.Л. Технология программирования на VB.NET: учебное пособие. Уфа: УГАТУ, 2014. 225 с.
В современной программной инженерии в процессе проектирования, написания и отладки программных продуктов нередко приходится решать вопросы, связанные с определением и последующей оптимизацией времени выполнения программного кода [1]. Не меньший интерес представляют вопросы, связанные с оценкой времени выполнения того или иного кода, написанного на различных языках программирования и на различных компьютерных платформах [2]. Определение времени выполнения программного кода критично:
– для приложений, обрабатывающих данные в режиме реального времени, например приложений, реализующих функции управления техническими устройствами;
– при решении инженерных и научно-технических задач, в которых производятся сложные длительные вычисления, а процессорное время дорого и ограничено, например в задачах проектирования и расчета сложных технических объектов;
– при разработке программ, работающих с аппаратной частью компьютеров, например драйверов для различных устройств;
– для процессов обработки больших данных, требующих значительных временных затрат, например при проведении маркетинговых исследований;
– при генерации страниц в web-приложениях, в которых время критично для пользователя и напрямую связано с производительностью серверов;
– для процессов измерения скорости передачи данных в коммуникационных системах;
– при проведении всевозможных тестирований и др.
В процессе разработки программного обеспечения нередко возникает необходимость отладки фрагментов кода, критичных по времени исполнения, для выявления «узких мест» выполнения программы, потребляющих чрезмерное количество ресурсов [3]. Время выполнения программного кода – это один из важнейших ресурсов, определяющих уровень качества программного продукта, наряду с такими показателями, как функциональные возможности, надежность, практичность, сопровождаемость и мобильность [4]. Оптимизация производительности программного продукта путем сокращения времени выполнения программного кода особенно важна, если он разрабатывается в расчете на длительный жизненный цикл и массовое использование при высоких требованиях к его качеству.
Цель исследования – измерение времени выполнения программного кода c использованием методов класса Stopwatch технологии .Net в ОС Windows для оценки качества программного продукта.
Материалы и методы исследования
Измерение времени выполнения программного кода будем выполнять в ОС Windows (Windows 10 Pro, 64-разрядная), как в одной из самых распространённых в настоящее время операционных систем. В качестве системы программирования используем Microsoft Visual Studio 2013 и язык программирования C#. Описанные ниже возможности измерения времени можно одинаково использовать как в Visual C# .NET, так и Visual Basic .NET, в Visual C++ .NET и Visual J# .NET.
Для проведения измерений применим специальные проблемно-ориентированные методы класса Stopwatch на технологической платформе .Net. Класс Stopwatch основан на HPET (High Precision Event Timer – таймер событий высокой точности). Таймер HPET разработан Microsoft с целью устранения проблем с измерением времени выполнения того или иного программного кода. Частота таймера HPET (минимум 10 МГц) не меняется во время работы системы. Каждая версия OS Windows сама определяет, с помощью каких устройств следует реализовать этот таймер.
Существует несколько способов измерения интервалов времени в ОС Windows. Например, функция timeGetTime возвращает системное время в миллисекундах достаточно точно, однако работает медленно из-за многочисленных промежуточных вызовов и преобразований. Функция GetTickCount работает быстро, но имеет невысокую точность 15 мс (для Windows XP), так как использует прерывания, генерируемые часами реального времени компьютера.
Более точный метод измерения времени в ОС Windows – использование пары функций QueryPerformanceCounter [5] и QueryPerformanceFrequency [6]. Функция QueryPerformanceCounter возвращает текущее значение в тиках, а функция QueryPerformanceFrequency возвращает частоту счетчика производительности. Эти функции работают быстро и имеют высокую точность, так как используют таймер высокой точности High Precision Event Timer (HPET). Временной промежуток между «тиками» этого таймера меньше 1 мс, что позволяет производить достаточно точные измерения [7].
В библиотеке классов FCL каркаса Framework имеется класс Stopwatch [8], который также работает с таймером высокого точности High Precision Event Timer и предоставляет удобный набор средств, используемых для измерения времени. Публичный API класса Stopwatch инкапсулирует следующий набор свойств (табл. 1) и методов (табл. 2).
Свойства публичного API класса Stopwatch
Возвращает общее затраченное время, измеренное текущим экземпляром