Лучший способ расчета ETA операции?
Я ищу лучший способ вычисления ETA операции (загрузка IE: файл) с использованием информации о линейном ходе.
Давайте скажем, что у меня есть следующий метод, который вызывается:
void ReportProgress(double position, double total)
{
...
}
У меня есть пара идей:
- рассчитать прогресс в заданное время (например, последние 10 секунд) и использовать эту скорость как среднюю скорость для операции
- сохранить набор последних x progresses, о которых сообщалось, рассчитать скорость каждого приращения и использовать средний
Ответы
Ответ 1
Я действительно презираю обе эти идеи, потому что они оба укусили меня раньше, как разработчика.
В первую очередь не учитывается ситуация, когда операция действительно ускоряется, она говорит, что там 10 минут, и я возвращаюсь после 3, и она закончилась.
Второе не учитывает, что операция становится медленнее - я думаю, что Windows Explorer должен использовать этот метод, поскольку он всегда, кажется, занимает 90% времени, копируя 90% файлов, а затем еще 90% времени копирует последние 10% файлов: -).
Я уже давно собираюсь рассчитать эти цифры и усреднить их. Клиентам это не волнует (на самом деле они не заботятся о двух других вариантах: они просто хотят увидеть некоторый прогресс), но это заставляет меня чувствовать себя лучше, и это действительно все, о чем я забочусь в конце дня; )
Ответ 2
Что-то вроде этого должно сделать трюк:
void ReportProgress(double position, double total)
{
static TimeType startTime;
if (position == 0)
{
startTime = GetTime();
return; // to avoid a divide-by-zero error
}
TimeType elapsedTime = GetTime() - startTime;
TimeType estimatedRemaining = elapsedTime * total / position;
TimeType estimatedEndTime = GetTime() + estimatedRemaining;
// Print the results here
}
Оценка приближается к истине, поскольку прогресс приближается к 100%
Ответ 3
Я думаю, что эта проблема в значительной степени неразрешима, но можно создать некоторые точные оценки, немного познав процесс, который выполняется. И в тех случаях, когда есть большие неизвестные, лучше информировать пользователя о тех неизвестных, чтобы они могли учитывать их.
Чтобы взять простой пример загрузки пакета файлов, у вас есть две известные переменные:
- Количество файлов
- Размер файлов
Для каждого файла есть постоянная накладная (время, необходимое для установления соединения, и время, необходимое для открытия файла в файловой системе). Существует также очевидное время загрузки, связанное с размером файлов. Создание функции, которая может выразить это, поскольку время, оставшееся с точки зрения текущей скорости загрузки, является простым и точным, если скорость downlaod не слишком сильно колеблется. Но есть проблема.
С помощью точной модели операции, которую вы выполняете, легко предсказать, сколько времени потребуется, если нет внешних воздействий. И это редко бывает возможно.
Однако вы могли бы пойти на решение, которое пытается понять и объяснить эти внешние влияния. Пользователь может сочтет полезным быть предупрежденным, когда скорость резко изменится, поскольку они могут скорректировать свои планы в соответствии с новой ETA. Также может быть полезно объяснить, какие факторы влияют на текущую операцию. например,
Your download will complete in 6 minutes, if the download speed stays at 50k/s
Это позволяет пользователю делать некоторые обоснованные предположения, если они знают, что скорости могут измениться. И в конечном итоге приводит к меньшему разочарованию.
Ответ 4
Брэм Коэн говорил об этом немного. Он приложил немало усилий в вычислениях ETA в BitTorrent (но в разговоре он упомянул, что никто еще не подошел к нему и не сказал "эй! Великие расчеты ETA в битторанте!" ). Это не простая проблема.
Некоторые релевантные ссылки:
Ответ 5
Если вы хотите ETA, а не "индикатор выполнения", можете ли вы предоставить более одной цифры?
Рассчитайте среднюю скорость загрузки в течение заданного периода времени (в зависимости от того, как долго длится полная загрузка, если вы смотрите на 10+ минут, то каждые 5 или около того будет нормально) и сохраните запись средние значения.
Затем вы можете указать две цифры, верхнюю и нижнюю оценки.
Если вы уверены, что средние показатели будут хорошим показателем общего времени для загрузки, тогда вы можете отобразить 40-й процентиль и 60-е - если среднее время загрузки сильно варьируется, тогда 10 и 90-е могут быть лучше.
Я бы предпочел увидеть стадион "21 -30 минут", и это было бы точно, если бы было сказано 29 минут 35,2 секунды, и это было далеко, и дико варьировалось от одного обновления к другому.
Ответ 6
В Python:
>>> done=0.3; duration=10; "time left: %i" % (duration/done-duration)
'time left: 23'
Ответ 7
Это будет зависеть от того, насколько согласуется время операции. Если это будет согласовано, было бы разумно использовать среднее время предыдущих операций. Если это не так, вам лучше отменить текущую операцию и экстраполяцию.
Изменить: Если операция несовместима с предыдущими запусками, а также несовместима с начала до конца, тогда у вас есть проблема с неразрешимостью. Прогнозировать непредсказуемое всегда весело:)
Вы можете решить заблаговременно, если хотите недооценивать или переоценивать, и добавить к расчету коэффициент вымывания. Например, если вы хотите переоценить, а первые 10% занимают 6 секунд, вы можете экстраполировать до 60 секунд, а затем умножить на 1,5, чтобы получить общую оценку в 90 секунд. По мере того, как процентное соотношение возрастает, уменьшайте коэффициент вымывания до 100% и становитесь 1.0.
Ответ 8
Я работал над проектом, требующим ETA длительного и трудоемкого вычисления, и то, что я делал, было разделение процесса партиями того же размера. Затем, время, необходимое для вычисления каждой партии, и время, затраченное на добавление, добавляется в список прошлых вычислений FIFO.
Затем время в списке усредняется, и полученное время умножается на количество оставшихся партий.
number of batches = N
size of batch = x
past computations length = l (t0,t1,...,tl)
avg time per batch = (t0 + t1 + ... + tl) / l = t
computed batches = n
ETA = t * (N - n)
Обратите внимание, что список имеет фиксированную длину, которая должна быть достаточно длинной, чтобы процесс оценки "помнил" и настраивался на возможные пики при вычислении, но он также должен быть достаточно коротким, чтобы быстро адаптироваться к изменениям скорости вычислений (например, больше времени вычисления конец конкурирующей задачи/большая пропускная способность)