v8: Эстиматор - защита пользователя от стрессаВ данном разделе рассказано, как правильно подсчитывать время, через которое завершится цикл с заранее известным количеством повторений и показывать это время пользователю. | | Автор статьи: Гений 1С | Редакторы: Последняя редакция №5 от 28.04.06 | История URL: http://kb.mista.ru/article.php?id=185 | |
Ключевые слова: эстиматор,время,состояние,цикл
Слово Эстиматор в данном контексте применил впервые я, Гений 1С. Происходит от английского estimated time - оставшееся время работы.
Очень часто при выполнении длительных циклов с заранее известным количеством повторений имеет смысл выдавать пользователю информацию о том, сколько объектов обработано, сколько еще нужно обработать и приблизительное время окончания работы.
Пусть:
* I - номер текущего прохода (1..N)
* N - количество всех проходов
* T0 - время начала
* TI - текущее время, когда выполняется проход I
Тогда прогнозируемое время в случае равномерной скорости обработки равно T0+ (TI-T0) / I * (N-I).
Однако часто на практике мы обрабатываем таблицы, где некоторые элементы пропускаются, т.е. выполняются практически за 0 секунд. Такие случаи существенно портят нам статистику и ухудшают результат предсказания.
Для таких случаев мы введем дополнительный параметр Pass, который будет хранить количество пропущенных проходов. В начале он устанавливается равным нулю, и при каждом пропуске будет увеличиваться на единицу.
Более точная формула прогнозируемого времени: T0+ (TI-T0) / (max(I-Pass,1)) * (N-I).
Пусть мы начали в T0=0 секунд, у нас объект обрабатывается 2 секунды или пропускается за 0 секунд. Например, мы обрабатываем N=100 объектов, Pass=80 первых пропустили, обработали еще 10 объектов по 2 секунды каждый, т.е. завершили обработку I=90 объектов и находимся на TI=20 секунде.
Эстиматор по простой первой формуле выдаст нам время обработки оставшихся 10 объектов как (20-0)/90*(100-90)=2 секунды.
Если мы применим уточняющую формулу, получим гораздо более реальный результат (20-0)/(90-80)*(100-90)=20 секунд.
Для реализации эстиматора самый красивый способ - структура или обработка. В любом случае в начале цикла устанавливается количество проходов и выводимое в строке состояния сообщения, метод Проход увеличивает счетчик на заданное число, метод Пропуск отмечает заданное количество пропусков.
Реализация эстиматора, как набора функций.
Шаблоны функций:
ЭстиматорСоздать()
ЭстиматорСтарт(Эстиматор, Всего=Неопределено)
ЭстиматорПроход(Эстиматор, Счетчик=1)
ЭстиматорПропуск(Эстиматор, Счетчик=1)
Пример кода:
Эстиматор=ЭстиматорСоздать()
Эстиматор.Сообщение="Демо-цикл";
Для Инд=1 По 100 Цикл
Если Инд<=80 Тогда
ЭстиматорПропуск(Эстиматор);
Продолжить;
Иначе
ЭстиматорПроход(Эстиматор);
Задержка(2); //2 секунды задержка
КонецЕсли;
КонецЦикла;
Реализация эстиматора как обработки.
Или же в духе ООП создать обработку Эстиматор. Этот вариант мне нравится больше, хотя для первого достаточно только функций. Дополнительно в обработке можно указать свою форму эстиматора, которую выводить как прогрессор.
Шаблоны функций:
Эстиматор=Новый Обработки.Эстиматор
Эстиматор.Старт(Всего=Неопределено)
Эстиматор.Проход(Эстиматор, Счетчик=1)
Эстиматор.Пропуск(Эстиматор, Счетчик=1)
Эстиматор=Новый Обработки.Эстиматор;
Эстиматор.Сообщение="Демо-цикл";
Для Инд=1 По 100 Цикл
Если Инд<=80 Тогда
Эстиматор.Пропуск();
Продолжить;
Иначе
Эстиматор.Проход();
Задержка(2); //2 секунды задержка
КонецЕсли;
КонецЦикла;
Также в некоторых формах типовых конфигураций есть формы вывода прогрессоров. Их также опционально можно подключать в нашем эстиматоре, через свойства переменной Эстиматор.
Возможна реализация как в 77, так и в 80.
|