Почему индикаторы прогресса так неточны?
На первый взгляд кажется, что точная оценка времени должна быть довольно простой. В конце концов, алгоритм, создающий индикатор выполнения, знает все задачи, которые он должен выполнить заранее… правильно?
По большей части, это правда, что исходный алгоритм действительно знает, что ему нужно делать заранее. Однако определение времени, которое потребуется для выполнения каждого шага, является очень сложной, если не практически невозможной задачей..
Все задачи не созданы равными
Самый простой способ реализовать индикатор выполнения - использовать графическое представление счетчика задач. Где процент завершения просто рассчитывается как Выполненных задач / Общее количество задач. Хотя это логично с первого взгляда, важно помнить, что (очевидно) выполнение некоторых задач занимает больше времени.
Рассмотрим следующие задачи, выполняемые установщиком:
- Создать структуру папок.
- Распакуйте и скопируйте файлы объемом 1 ГБ.
- Создать записи реестра.
- Создать пункты меню «Пуск».
В этом примере шаги 1, 3 и 4 будут завершены очень быстро, тогда как шаг 2 займет некоторое время. Таким образом, индикатор выполнения, работающий с простым подсчетом, очень быстро скачет до 25%, на некоторое время остановится, пока работает шаг 2, а затем почти сразу перейдет на 100%..
Этот тип реализации на самом деле довольно распространен среди индикаторов выполнения, потому что, как указано выше, его легко реализовать. Однако, как вы можете видеть, это связано с непропорциональными фактический Процент прогресса, как это связано с оставшимся временем.
Чтобы обойти это, некоторые индикаторы выполнения могут использовать реализации, где шаги взвешены. Рассмотрим шаги выше, где каждому шагу присвоен относительный вес:
- Создать структуру папок. [Вес = 1]
- Распакуйте и скопируйте файлы объемом 1 ГБ. [Вес = 7]
- Создать записи реестра. [Вес = 1]
- Создать пункты меню Пуск. [Вес = 1]
При использовании этого метода индикатор выполнения будет перемещаться с шагом 10% (так как общий вес равен 10) с шагами 1, 3 и 4, перемещающими индикатор на 10% по завершении, и шагом 2, перемещающими его на 70%. Хотя такие методы, конечно, не идеальны, это простой способ добавить немного больше точности в процент выполнения.
Прошлые результаты не гарантируют будущие результаты
Рассмотрим простой пример того, как я просил вас сосчитать до 50, пока я использую секундомер, чтобы подсчитать время. Допустим, вы считаете до 25 за 10 секунд. Было бы разумно предположить, что вы посчитаете оставшиеся числа в течение дополнительных 10 секунд, поэтому при отслеживании индикатора выполнения это будет показывать 50% с оставшимися 10 секундами..
Как только твой счет достигает 25, я начинаю бросать в тебя теннисные мячи. Вероятно, это нарушит ваш ритм, так как ваша концентрация перешла от строго подсчета чисел к уклонению от шаров, брошенных вам на пути. Предполагая, что вы можете продолжать считать, ваш темп, конечно, немного замедлился. Так что теперь индикатор выполнения все еще движется, но в гораздо более медленном темпе с предполагаемым временем, оставшимся либо в состоянии покоя, либо фактически поднимаясь выше.
Для более практического примера рассмотрим загрузку файла. В настоящее время вы загружаете файл размером 100 МБ со скоростью 1 МБ / с. Это очень легко определить предполагаемое время завершения. Но в 75% случаев возникают некоторые перегрузки сети, и ваша скорость загрузки падает до 500 КБ / с..
В зависимости от того, как браузер рассчитывает оставшееся время, ваш ETA может мгновенно перейти от 25 секунд до 50 секунд (используя только текущее состояние: Размер, оставшийся / Скорость загрузки) или, скорее всего, браузер использует алгоритм скользящего среднего, который будет корректировать колебания скорости передачи, не отображая значительных скачков для пользователя.
Пример скользящего алгоритма в отношении загрузки файла может работать примерно так:
- Скорость передачи за предыдущие 60 секунд запоминается с использованием новейшего значения, заменяющего самое старое (например, 61-е значение заменяет первое).
- Эффективная скорость передачи для целей расчета является средним из этих измерений.
- Оставшееся время рассчитывается как: Размер, оставшийся / эффективная скорость загрузки
Итак, используя наш сценарий выше (для простоты мы будем использовать 1 МБ = 1000 КБ):
- Через 75 секунд после загрузки наши 60 запоминаемых значений будут равны 1000 КБ. Эффективная скорость передачи составляет 1000 КБ (60 000 КБ / 60), что дает оставшееся время в 25 секунд (25 000 КБ / 1000 КБ)..
- При 76 секундах (когда скорость передачи падает до 500 КБ), эффективная скорость загрузки становится равной ~ 992 КБ (59 500 КБ / 60), что дает оставшееся время ~ 24,7 секунд (24 500 КБ / 992 КБ)..
- При 77 секундах: эффективная скорость = ~ 983 КБ (59 000 КБ / 60), оставшееся время до ~ 24,4 секунд (24 000 КБ / 983 КБ).
- Через 78 секунд: эффективная скорость = 975 КБ (58 500 КБ / 60), оставшееся время до ~ 24,1 секунды (23 500 КБ / 975 КБ).
Вы можете увидеть паттерн, появляющийся здесь, когда падение скорости загрузки медленно включается в среднее значение, которое используется для оценки оставшегося времени. При этом методе, если падение длилось всего 10 секунд, а затем вернулось к 1 МБ / с, пользователь вряд ли заметит разницу (за исключением очень незначительного срыва в расчетном отсчете времени).
Приступая к делу - это просто методология передачи информации конечному пользователю по фактической основной причине ...
Вы не можете точно определить что-то недетерминированное
В конечном счете, неточность индикатора выполнения сводится к тому, что он пытается определить время для чего-то недетерминированного. Поскольку компьютеры обрабатывают задачи как по требованию, так и в фоновом режиме, практически невозможно узнать, какие системные ресурсы будут доступны в любой момент в будущем - и именно доступность системных ресурсов необходима для выполнения любой задачи..
Используя другой пример, предположим, что вы запускаете обновление программы на сервере, который выполняет довольно интенсивное обновление базы данных. Во время этого процесса обновления пользователь затем отправляет требовательный запрос другой базе данных, работающей в этой системе. Теперь ресурсам сервера, особенно для базы данных, приходится обрабатывать запросы как на обновление, так и на запрос, инициированный пользователем - сценарий, который, безусловно, будет вреден для времени выполнения. С другой стороны, пользователь может инициировать большой запрос на передачу файла, который облагает налогом пропускную способность хранилища, что также снижает производительность. Или может начаться запланированное задание, которое выполняет процесс, интенсивно использующий память. Вы поняли идею.
Как, возможно, более реалистичный пример для обычного пользователя - рассмотрите возможность запуска Центра обновления Windows или проверки на вирусы. Обе эти операции выполняют ресурсоемкие операции в фоновом режиме. В результате, каждый прогресс зависит от того, что пользователь делает в данный момент. Если вы читаете свою электронную почту во время этого, скорее всего, спрос на системные ресурсы будет низким, и индикатор выполнения будет двигаться последовательно. С другой стороны, если вы занимаетесь редактированием графики, тогда ваши потребности в системных ресурсах будут намного выше, что приведет к шизофреническому движению индикатора выполнения..
В общем, просто нет хрустального шара. Даже сама система не знает, под какой нагрузкой она будет находиться в любой момент в будущем..
В конечном счете, это действительно не имеет значения
Целью индикатора выполнения является, ну, в общем, указать, что прогресс действительно достигнут, и соответствующий процесс не завис. Приятно, когда индикатор прогресса точен, но обычно это лишь незначительное раздражение, когда это не так. По большей части, разработчики не собираются тратить много времени и усилий на алгоритмы индикатора выполнения, потому что, честно говоря, есть гораздо более важные задачи, чтобы потратить время на.
Конечно, вы имеете полное право быть раздраженным, когда индикатор выполнения мгновенно переходит на 99%, а затем заставляет вас ждать 5 минут за оставшиеся 1%. Но если соответствующая программа в целом работает хорошо, просто напомните себе, что у разработчика были свои приоритеты.