Как оценить оставшееся время загрузки (точно)?
конечно, вы можете разделить оставшийся размер файла на текущую скорость загрузки, но если ваша скорость загрузки колеблется (и это будет), это не дает очень хорошего результата. Каков лучший алгоритм для создания более плавного обратного отсчета?
5 ответов
Я написал алгоритм несколько лет назад, чтобы предсказать время, оставшееся в программе формирования образа диска и многоадресной передачи, которая использовала скользящую среднюю со сбросом, когда текущая пропускная способность вышла за пределы предопределенного диапазона. Если не произойдет чего-то радикального, все будет идти гладко, потом все быстро изменится и снова вернется к скользящей средней. См. пример диаграммы здесь:
толстая синяя линия в этом примере диаграммы является фактической пропускная способность с течением времени. Обратите внимание на низкую пропускную способность во время первой половины передачи, а затем она резко возрастает во второй половине. Оранжевая линия - это общее среднее значение. Обратите внимание, что он никогда не настраивается достаточно далеко, чтобы точно предсказать, сколько времени потребуется для завершения. Серая линия-это скользящая средняя (т. е. среднее значение последних N точек данных - на этом графике N равно 5, но на самом деле N может быть больше, чтобы сгладить достаточно). Он восстанавливается быстрее, но все же нужно время, чтобы привыкнуть. Это займет больше времени, чем больше N. Поэтому, если ваши данные довольно шумные, то N должно быть больше, и время восстановления будет больше.
зеленая линия-это алгоритм, который я использовал. Это происходит так же, как скользящая средняя, но когда данные выходят за пределы предопределенного диапазона (обозначенного светло-тонкими синими и желтыми линиями), он сбрасывает скользящую среднюю и сразу же подпрыгивает. Предопределенный диапазон также может быть основан на стандартном отклонении, поэтому смогите отрегулировать к как шумно данные автоматически. Я просто бросил эти значения в Excel, чтобы отобразить их для этого ответа, поэтому он не идеален, но вы понимаете идею.
данные могут быть придуманы, чтобы этот алгоритм не был хорошим предиктором оставшегося времени. Суть в том, что вам нужно иметь общее представление о том, как вы ожидаете, что данные будут вести себя и выбрать алгоритм соответственно. Мой алгоритм хорошо работал для наборов данных, которые я видел, поэтому мы продолжали использовать он.
еще один важный совет заключается в том, что обычно разработчики игнорируют время установки и демонтажа в своих индикаторах выполнения и расчетах оценки времени. Это приводит к Вечному 99% или 100% прогресс-бар, который просто сидит там в течение длительного времени (в то время как кэши промываются или другая работа очистки происходит) или диких ранних оценок, когда сканирование каталогов или другой работы по настройке происходит, начисление времени, но не начисление какой-либо процент прогресса, который выбрасывает все. Вы можете выполните несколько тестов, которые включают время установки и демонтажа, и получите оценку того, как долго это время в среднем или на основе размера задания, и добавьте это время в индикатор выполнения. Например, первые 5% работы-это работа по настройке, а последние 10% - работа по демонтажу, а затем 85% в середине-это загрузка или любой повторяющийся процесс отслеживания. Это тоже может помочь.
An экспоненциальная скользящая средняя идеально подходит для этого. Это позволяет сгладить среднее значение, так что при каждом добавлении новой выборки старые выборки становятся все менее важными для общего среднего значения. Они все еще рассматриваются, но их значение падает экспоненциально-отсюда и название. И поскольку это" скользящая " средняя, вам нужно только сохранить одно число.
в контексте измерения скорости загрузки формула будет выглядеть это:
averageSpeed = SMOOTHING_FACTOR * lastSpeed + (1-SMOOTHING_FACTOR) * averageSpeed;
SMOOTHING_FACTOR
- это число от 0 до 1. Чем выше это число, тем быстрее отбрасываются старые образцы. Как вы можете видеть в Формуле, когда SMOOTHING_FACTOR
is 1 вы просто используете значение вашего последнего наблюдения. Когда SMOOTHING_FACTOR
от 0 averageSpeed
никогда не меняется. Итак, вы хотите что-то среднее, и обычно низкое значение, чтобы получить достойное сглаживание. Я обнаружил, что 0.005 обеспечивает очень хорошее значение сглаживания для средней скорости загрузки.
lastSpeed
- это последняя измеренная скорость загрузки. Вы можете получить это значение, запустив таймер каждую секунду или около того, чтобы вычислить, сколько байтов было загружено с момента последнего запуска.
averageSpeed
это, очевидно, число, которое вы хотите использовать для расчета расчетного оставшегося времени. Инициализируйте это до первого lastSpeed
измерения вы получите.
Я думаю, что лучшее, что вы можете сделать, это разделить оставшийся размер файла на среднюю скорость загрузки (загруженный до сих пор делится с тем, как долго вы загружали). Это будет колебаться немного, чтобы начать, но будет все более и более стабильным, чем дольше вы скачать.
в дополнение к ответу Бена Долмана вы также можете вычислить флуктуацию в алгоритме. Он будет более плавным, но он также будет предсказывать среднюю скорость.
что-то вроде этого:
prediction = 50;
depencySpeed = 200;
stableFactor = .5;
smoothFactor = median(0, abs(lastSpeed - averageSpeed), depencySpeed);
smoothFactor /= (depencySpeed - prediction * (smoothFactor / depencySpeed));
smoothFactor = smoothFactor * (1 - stableFactor) + stableFactor;
averageSpeed = smoothFactor * lastSpeed + (1 - smoothFactor) * averageSpeed;
флуктуация или нет, она будет такой же стабильной, как и другая, с правильными значениями для прогнозирования и depencySpeed; вы должны играть с ней немного в зависимости от вашей скорости интернета. Эти настройки идеально подходят для средней скорости 600 кб / с, в то время как колеблется от 0 до 1 МБ.